此文写于2019年,2022年2月对外同步。此文的内容集成了各博客、优质文章内容,若有侵权,请联系删除。
近两年前端领域风云变幻,各种技术栈层出不穷。React、Angular、Vue 逐步三分天下,Webpack + Babel + ES6 模式如日中天,PostCSS 大有取代 SASS、LESS、Stylus 的趋势,还有 HTTP2、WebComponents、WebAssembly、函数式编程等新概念不断涌现。让前端工程师应接不暇、感叹不已:“今年一个技术还没学会,明年可能就不用学了。”
回顾前端发展历史,按照《前端开发技术的发展》一文中的观点,大概可以分为三个阶段:
-
刀耕火种:典型特征是服务器语言(ASP、JSP、PHP)为主,结合简单的 CSS 和 JS 代码片段。是最早期的 WebPage 模式;
-
手工工场:典型特征是 Ajax 的出现,它使得 WebApp 模式成为可能。这期间 jQuery、Prototype 和 Mootools 几个库占主导地位,并出现了初步的模块加载方式;
-
工业革命:典型特征是各种 MV*框架的不断出现,各种开发模式的不断演进,各种自动化工具的不断革新,各种标准的不断确立。
2015 年 ES6 标准的确立标志着前端领域正式进入了蒸汽时代。但离流水线作业的电气时代还有一段路要走。
相对于去年剧烈的变革,今年的前端生态有所缓和。乘着工业化浪潮,ADA 前端本着面向未来、稳步推进的原则,也对项目架构进行了优化改进,并确立了新的发展方向。
关于前端架构的工业化,主要应该从模块化、组件化、规范化和自动化四大方面考虑,下面一一展开:
模块化
分工产生效能
模块化是“刀耕火种”和“手工工场”的分界线。它的作用是将一个大文件拆分成相互依赖的小文件,再进行统一的拼装和加载,这为多人协作提供了可能。
JS 的模块化
在 ES6 之前, 社区制定了一些模块加载方案,如 CommonJS、AMD 和 CMD 等, 这对开发大型复杂的前端工程造成了巨大的障碍。ES6 已经在语言层面上,规定了模块系统,而且使用起来相当方便,完全可以取代现有的 CommonJS 和 AMD 规范。
如果你想使用 ES6:
- IE6、7 就不用考虑了;
- IE8在项目中不能使用export * from 'xxx'这个功能,但不能保证使用的依赖库中没有用到,具体请参考使React 应用兼容 IE8
- IE9+ 只需吃个 babel-polyfill 就能完美使用
打包工具,目前来说最好的非 Webpack 莫属。因此,技术选型:Webpack + Babel + ES6
CSS 的模块化
虽然 SASS、LESS、Stylus 等预处理器实现了 CSS 的文件拆分,但没有解决 CSS 模块化的核心问题:选择器的私有化问题(全局污染问题)。 为了避免全局选择器的冲突,各厂都制定了自己的 CSS 命名风格:
- BEM 风格;
- Bootstrap 风格;
- Semantic UI 风格;
- ...
与其费尽心思地告诉别人要遵守某种规则,以规避某种痛苦,倒不如从工具层面就消灭这种痛苦。
从工具层面,社区又创造出 Shadow DOM、CSS in JS 和 CSS Modules 三种解决方案:
-
Shadow DOM 是 WebComponents 的标准。它能解决全局污染问题,但也使样式彻底私有化了,造成外部无法重写,损失了灵活性;
-
CSS in JS 是彻底抛弃 CSS,使用 JS 或 JSON 来写样式。这种方法很激进,不能利用现有的 CSS 技术,而且处理伪类等问题比较困难;
-
CSS Modules 仍然使用 CSS,只是让 JS 来管理依赖。它能够最大化地结合 CSS 生态和 JS 模块化能力,目前来看是最好的解决方案。
技术选型:PostCSS + CSS Modules(或 Scoped CSS)。
组件化
现代化生产的分工协作要求工业部件遵循互换性原则。
当前最火的 React 带头掀起了组件化浪潮,随后 Vue、Polymer、Angular2 等各种组件化框架 / 类库如雨后春笋般出现。
组件化的概念
组件化≠模块化
-
模块化只是在语言层面上,对代码的拆分;而组件化是基于模块化,在设计层面上,对 UI(用户界面)的拆分。
从 UI 拆分下来的每个包含模板 (HTML)+ 样式 (CSS)+ 逻辑 (JS) 功能完备的结构单元,我们称之为组件,这其实是一种分治(分而治之)思想。
-
组件化是一种在设计层面上,对项目中 UI 进行整体的疏理和拆解,再按照 HTML+CSS+JS 三位一体的面向对象来进行封装的过程或思想。
比如 Vue 的*.vue 单文件结构
-
组件系统它提供了一种抽象,让我们可以用独立可复用的小组件来构建大型应用。
如果我们考虑到这点,几乎任意类型的应用的界面都可以抽象为一个组件树:
组件的分类
按照组件的代码组成,组件可以分为:HTML、HTML+CSS、JS、HTML+JS、HTML+CSS+JS。
按照组件的通用性(复用性),组件可以分为以下三类:
- 通用组件:不同产品间可以复用的组件。
- 通用业务组件:仅在同一产品中可以复用的组件。
- 业务组件:不可以复用的组件。比如具体场景中使用的组件,一次性的业务模块等。
组件的一个设计原则是:在不增加组件配置复杂度的情况下,尽可能的提高组件通用性。
组件之间的关系
组件之间的关系有继承、扩展和嵌套,还有包含,表示一个组件内部调用了另一个组件。这些关系都可以归属为依赖。
组件库
组件库是一系列组件的集合。 如Element-UI、ANT DESIGN等等
规范化
现代工厂制度是工业革命发展的必然产物。
模块化和组件化确定了开发模型,而这些东西的实现需要规范去落实,如:
- 目录结构:源文件和目标文件完全分开,依赖统一用 npm 进行包管理。
- 编码规范:JS/CSS Lint
自动化
现代工业其所以区别于工场手工业,是由于机器起了主要的作用。自动化是“手工工场”和“工业革命”的分水岭。
-
静态资源合并:图标合并(雪碧图、字体图标);JS、CSS 代码合并压缩
-
可视化组件文档:前端开发和后端开发不同的是,前端开发是可视化的。组件示例和文档内容,可参考上面提到的几个组件库的文档。
-
前端自动化测试
遵循维护自动化测试成本最低原则,在项目中只覆盖:
a、基础类库的单元测试;
b、通用组件和通用业务组件的单元测试;
c、通用组件和通用业务组件简单的 UI 测试。
d、必要的 e2e 测试
技术选型:Karma + Mocha Jest、TestCafe (2022 年修改)
构建工具
目前 Gulp 是处理工作流的最佳选择,没有之一。
条件允许建议使用 vite 等 bundleless 构建工具,
不过构建项目各阵营均有自己的脚手架:Vue-cli、create-vuegithub.com/vuejs/creat…](www.npmjs.com/package/rea…](github.com/angular/ang…)