2.1 项目概览
工程化简介 && package.json
上一章节中用了 5 节篇幅 ElementUI 源码学习:从零开始搭建 Vue 组件库汇总 讲解了如何编写一个组件、发布 npm 以及生成展示文档。接下来将分析 Element 项目的代码结构,学习其工程化思想。
前端工程化是什么?
前端开发早已从瘦客户端(thin client)架构/中心服务器(server-centric)架构进入到胖客户端(fat client)架构,各家技术百花齐放,让人目不暇接,直呼学不动了!伴随项目开发的复杂度日益增高,开发中需要直面各种问题: 开发效率、产品质量、多人协作等。
前端工程化 就是为了应对上述问题,把软件工程相关的方法和思想应用到前端日常开发中,以 系统化的、规范化的、可度量的方法 用于前端项目的开发、运行和维护等阶段,从而提高开发效率、提高产品质量、减少不必要的重复工作时间、降低开发难度/风险、降低企业成本(降本增效)。
如今前端项目的开发、构建、部署等主要环节,涉及了项目构建、代码开发、分支管理、自动化测试、持续集成、项目部署、性能等内容。如何用工程化的思想让开发更加系统化、标准化?主要分为 模块化(组件化)、规范化、自动化 等多个方面。
1️⃣ 模块化
项目按照其功能/业务拆分成相互独立的模块,可以独立运行。每个模块只包含与其功能相关的内容,模块之间通过接口调用,降低模块间的耦合。 将一个大的系统模块化之后,每个模块都可以被高度复用。模块不等于功能,一个功能可能包含多个模块(功能 > 模块)。
模块化让项目便于依赖管理、利于性能优化、提高可维护性。 各技术实现方案如下:
JS 的模块化(CommonJS、 AMD、 CMD、UMD、ES6 Module)
CSS 的模块化(BEM 命名规范、CSS Module、CSS In JS)
资源模块化(webpack loaders)
2️⃣ 组件化
组件化是为了解决项目代码重复问题,将其拆分成多个独立的组件给不同的功能使用,提高系统的代码重用(复用)性和易维护性。
📝 模块化 vs 组件化
组件化和模块化的中心思想都是 分而治之
, 将一个项目拆分成更小的颗粒度的单元(组件/模块
),降低业务开发的复杂度。
模块化、组件化它们术语是相似的,作为分治思想的体现,最终都实现了
高内聚,低耦合
。 通常认为“模块”比“组件”大。 项目模块化不一定要求组件化,在进行模块化拆分时可以完全不考虑代码重用。一般不会这么做,这不是 best practice。 组件化就如 UI 控件,可以在各个模块中使用。而模块化就比如一个消息列表界面,引用 table 组件实现。虽然它没有复用的需求,但我们也要把它封装成独立模块。
3️⃣ 规范化
规范是团队基本约定的内容,必须严格遵循,旨在增强团队开发协作、提高代码质量。
目录结构 (约定俗称)
编码规范[HTML、CSS、JS、图片、命名等规范] (eslint、prettier)
前后端接口规范 (Swagger RESTful)
组件文档规范
Git 分支管理 (Git Flow )
Commit 描述规范 (Commitizen)
设计规范 (Material Design、Ant Design)
4️⃣ 自动化
将工作流程内容标准化,通过工具实现全/半自动化完成重复的工作,减少人的操作,实现标准统一、高质量交付。
文件构建 (webpack)
持续集成/构建/部署 (Travis CI)
自动化测试 (Jasmine、Mocha+chai、Jest)
下面将通过解析 element 项目源码,从结构、功能、源码方面逐一解析,学习其模块化、组件化、规范化、自动化等多维度学习 element 的优秀实践。
项目目录结构
package.json
接下来将从package.json
文件看起,快速了解分析项目 。
package.json
是项目的清单, 定义了这个项目所需要的各种模块,以及项目的配置信息(比如名称、版本、许可证、git 仓库等元数据)。
之前在 05.项目发布配置(github pages&npm package) 文章中提到了package.json
配置信息,下面将对element
项目的各项属性进行分析。
项目的 package.json
中有非常多的属性,可以大致分为以下几类:
必备属性(
name
、version
)描述信息(
description
、keywords
、homepage
、repository
、bugs
)NPM 脚本(
scripts
)依赖(
dependencies
、devDependencies
、peerDependencies
)协议(
license
) 指定软件的开源协议类型目录文件相关(
main
、files
、typings
、faas
、unpkg
、style
)
必备属性
name
和 version
属性是必须的字段,这两个属性组成一个 npm 模块的唯一标识。
name
是一个包的唯一标识,包名不能重复,可以执行 npm view packageName
查看包名是否已被占用,并可以查看一些基本信息
依赖
根据此配置信息,运行 npm || yarn install
命令,自动下载所需的模块,也就是配置项目所需的运行和开发环境。
NPM 脚本
指定了运行脚本命令的 npm 命令行缩写,覆盖整个项目的生命周期。下文将重点着墨讲解。
描述信息
记录项目的简介、关键字、项目主页、代码仓库、反馈 issues 等元信息。
协议
开源协议很多有很多,如何为自己的项目选合适的开源协议呢? 可以到 https://choosealicense.com/ 获取更详细的说明和指引。
目录文件相关
main
main
属性指定程序的主入口文件,当在应用程序中导入此软件包时,应用程序会在该位置搜索模块的导出。在代码中引入整个 Element import ElementUI from 'element-ui';
,实际上引入的就是 lib/element-ui.common.js
中暴露出去的模块。
files
files
属性用于描述 npm publish
后推送到 npm 服务器的文件列表,如果指定文件夹,则文件夹内的所有内容都会包含进来。也可以通过配置 .npmignore
文件来忽略文件上传。
typings
typings
属性指定针对 typescript 的声明文件入口。
详细参考 TypeScript docs.
style
style
属性指定了样式入口文件。
unpkg
unpkg
是一个前端常用的公共 CDN,它通过 URL 语法可以访问 NPM 上任何包的任何文件。
当把包发布到 npm 上时, 不仅可以 NodeJs 环境使用,也可以通过 unpkg 获取在浏览器环境执行,不过需要符合 umd
规范。
main
属性值lib/element-ui.common.js
是 commonjs
规范,由build/webpack.common.js
打包生成。unpkg
属性值 lib/index.js
是 umd
规范,由build/webpack.conf.js
打包生成。关于打包模块功能会稍后详细说明。
设置 unpkg
属性后,访问 https://unpkg.com/element-ui,按照上述规则自动访问 https://unpkg.com/element-ui@2.15.1/lib/index.js。
在之前的me-vue-ui
包发布中,由于没有配置 unpkg
属性,访问 https://unpkg.com/me-vue-ui 时按照 main
属性定义的文件路径自动访问 https://unpkg.com/me-vue-ui@0.1.2/lib/me-vue-ui.common.js。
CDN 引入
若浏览器环境引入组件,只需要通过 unpkg.com/element-ui 获取到资源,在页面上引入 js 和 css 文件即可开始使用。 CSS 文件的路径是 style
属性值;js 文件的路径是基于umd
规范的打包文件的路径--unpkg
属性值。
faas
用于faas deploy
配置。NPM 脚本的pub
命令存在 sh build/deploy-faas.sh
调用,用于站点element.eleme.io
的发布部署,不过在 2.15 版本之后被移除了(具体使用情况无法重现)。详见 commit feat: add change log 2.15.0 (#20692)
关联阅读
点击以下链接,可以快速查看本系列其他文章: 专栏/Element 2.X 源码学习
👇 项目工程化系列文章链接如下,推荐按照顺序阅读文章 👇。
1️⃣ 源码剖析之工程化:项目概览、package.json、npm script 2️⃣ 源码剖析之工程化:项目构建、MD 解析 3️⃣ 源码剖析之工程化:打包配置 4️⃣ 源码剖析之工程化:发布部署、持续集成 5️⃣ 源码剖析之工程化:主题构建、自动化测试、代码质量检查、类型声明 6️⃣ 源码剖析之工程化:项目网站 7️⃣ 源码剖析之工程化:命令之图解
最后更新于