什么是前端工程化
我们都知道,当代前端工程已经从 Page
级别 上升到 App
级别了。并且Web
业务的 复杂化 和 多元化 还在日益提升当中。
这个时候,前端便会面临以下问题:
- 大体量:多功能、多页面、多状态、多系统;
- 大规模:多人甚至多团队合作开发;
- 高性能:
CDN
部署、缓存控制、请求合并、按需加载、同步/异步加载、移动端首屏CSS
内嵌、HTTP2
服务端资源推送。
如果没有 科学 的 管理方法 和 技术手段 的约束。时间,成本会不断上升,代码质量 会不断下降。最后变得难以维护,引发 软件危机 。而 软件工程 便是为了应对 软件危机。
因此,我们也必须以 软件工程 的角度来对待前端开发。来思考以下几个问题:
如何高效的多人协作?
如何提供开发效率?
如何提升开发质量?
如何提升项目可维护性?
如何降低项目生产问题?
软件工程(Software Engineering
),简称SE
。旨在将系统化的、严格约束的、可量化的方法应用于软件的开发、运行和维护,即将工程化应用于软件。
那么,前端工程化便是运用 软件工程 的 技术 和 方法,让前端开发流程、技术、工具、经验等更加 规范化、标准化。主要目的是为了提高开发效率,提升代码质量,并在项目不断迭代过程中保证 良好的可维护性 和稳定性。
软件工程核心思想
有这样一个公式:SE = 过程 + 方法 + 工具
过程: 解决 软件开发周期 中的 混乱 问题,构建高质量软件。
- 软件开发周期:设计,需求分析,开发,联调,测试,部署,维护,不断迭代。
- 形成 和 规范 开发流程。因地制宜,制定和不断修正,形成适合自己团队的开发流程规范。
方法 : 是指在整个过程中,如何构建系统的方法学。主要手段:
复用:在一个新系统中,大部分的内容是成熟的,只有小部分内容是全新的;复用已有的功能模块,既可以提高开发效率,也可以改善新开发过程中带来的质量问题。
分治:将复杂问题分解为若干可独立解决的简单子问题,并分别独立求解,以降低复杂性;然后再将各子问题的解综合起来,形成最初复杂问题的解。
- 核心问题:怎样的分解策略可以使得软件更容易理解、开发和维护?
折中:不同的需求之间往往存在矛盾与冲突,需要通过折中来作出的合理的取舍,找到使双方均满意的点。
- 核心问题:如何调和矛盾(需求之间、人与人之间、供需双方之间,等等)
演化:软件系统在其生命周期中面临各种变化。要游刃有余的应对这种变化。
- 核心问题:在设计软件的初期,就要充分考虑到未来可能的变化,并采用恰当的设计决策,使软件具有适应变化的能力。
工具: 我们需要工具来辅助方法的执行,提高效率。
- 通过工具,可以把一些手动的工作自动化,比如自动化测试工具,自动构建部署工具;
- 通过工具,可以帮助把一些流程规范起来,比如
Bug
跟踪、源代码管理; - 通过工具,帮助提高编码效率,比如各种编辑器
IDE
、插件等。
任何简单机械的重复劳动都应该让机器去完成。
前端工程化实践
假设一个前端工程要从 0
开始,我们可以把前端工程化实践分为3个阶段:
- 准备阶段:技术选型;架构设计;业务分治。
- 开发&迭代阶段:如何高效,高质量的进行需求开发,功能迭代。并保证良好的可维护性。
- 部署&维护阶段:自动化打包部署;
CI/CD
;生产问题定位;性能优化;
前端是一种技术问题较少、工程问题较多的软件开发领域。
准备阶段
该阶段有三个主要任务:
技术选型:业务场景,公司情况,团队情况三者相结合,选择合适的主框架(比如,
React
,Vue
),衍生库(如NextJS
,AntDesign
)以及各类管理工具选择。- 比如,该业务是定制化较强的,面向
C
端用户的H5
页面;团队成员技术栈以React
为主。那么可以选择React
主框架,然后规划自己的UI
库,工具库,业务组件库等。 - 比如,该业务是
BE
后台管理系统,面向内部运营人员。那么可以直接选择阿里开源的AntDesign
或者IceWork
。自带成熟物料,UI
组件库等,可以大大降低开发和维护成本。 - 比如,你的BE后台存在大量的
Form
表单操作,可以使用开源的form-render
配置化方案来提升开发效率。 - 工具选择:比如代码管理工具,一般是
Git
,要制定和严格执行 分支管理策略;包管理器,你可以直接使用npm
,推荐yarn
。开发工具,主流是VScode
,可以选装一系列辅助插件,也可以diy插件。
- 比如,该业务是定制化较强的,面向
架构设计:结合自身业务场景和环境,全面考虑,进行合理的架构设计,即使你使用
IceWork
这种自身生态全面的框架。- 比如,对架构进行分层管理,比如设置共享层( 底层UI组件库,公共业务组件库,util工具库等 ),定制层( 功能页面等 )。
业务分治:业务分类,划分子系统;通过单独的
Git
仓库进行子系统管理。- 最好建立自己的脚手架工具,子系统通过脚手架统一初始化。
- 权限管理,责任到人。
开发&迭代阶段
前面有提到,这个阶段的主要任务是如何高效,高质量的进行需求开发,功能迭代。并保证良好的可维护性。
目前,我们主要通过以下几个几个方面来进行约束:
- 模块化
- 组件化
- 规范化
模块化:
前端的模块化已经由来已久,已经形成了成熟的进行技术体系。
JS
模块化: 从之前的 RequireJS
(AMD
)、SeaJS
(CMD
) 到现在的 CommonJS
、ES6 Module
。
CSS
模块化: 我们还可以使用 Less
、Sass
、Stylus
等预处理器,对 CSS
进行模块化管理。
资源模块化: Webpack
更是把模块化推向极致,其核心思想是:一切皆模块,除了 JS
和 CSS
,还包括 imgage
,iconFont
等静态资源。
组件化:
组件化应用了 分治 和 复用 的思想。通过组件化,我们的所有页面都像是通过积木(组件)组合而成。
组件不只包括 UI
组件,还可以是不含 UI
的功能性组件。
组件化追求 小而美。问题是我们在抽象组件的时候,如何达到 小 和 美 的平衡,并不是拆分的越细越好。还有考虑 组件 的 复用性 和 可拓展性。
规范化:
形成一系列规范,并不断完善。严格执行,做好过程管理。
编码规范
组件规范
接口规范
文档规范
规范重要,更重要的规范的执行力度。自觉可能是最重要的,但又是最不可靠的。还是需要一些干预措施:
实行
codeReview
。使用
ESlint
,Husky
,Git hooks
等工具约束。
部署&维护阶段
该阶段的核心是 自动化。
首先,前端需要本地 Dev
调试 和 生产打包构建。可以使用 Gulp
, Webpack
, Babel
等工具库,添加配置文件,编写打包脚本来实现。
Gulp
是基于Nodejs
的自动任务运行器,它能自动化地完成javascript/sass/less/html/image/css
等文件的的测试、检查、合并、压缩、格式化、浏览器自动刷新、部署文件生成,并监听文件在改动后重复指定的这些步骤。优势是利用流的方式进行文件的处理,使用管道(pipe
)思想,前一级的输出,直接变成后一级的输入,通过管道将多个任务和操作连接起来,因此只有一次I/O
的过程,流程更清晰,更纯粹。Gulp
去除了中间文件,只将最后的输出写入磁盘,整个过程因此变得更快。Webpack
是一个模块打包工具,它的作用是把 互相依赖 的 模块 处理成 静态资源。其核心思想是一切皆模块。Babel
是一个JavaScript
编译器。负责把浏览器不认识的语法,编译成浏览器认识的语法。Webpack
中可以通过babel-loader
使用babel
。
可以通过一些 平台 实现 自动化部署 以及 CI/CD
。比如 Jenkins
,广泛使用的开源CI / CD
工具之一。它基于Java
,可以自动执行与软件的构建,测试,部署和交付相关的任务。可在Windows
,macOS
和其他Unix
版本上使用。
这些 CI/CD
平台都会用到 容器技术,我们也可以了解一下:
Docker
:Docker
是一个开源的应用容器引擎,开发者可以打包他们的应用及依赖到一个可移植的容器中,发布到流行的Linux
机器上,也可实现虚拟化。kubernetes
: 简称k8s
, 是一个开源的容器集群管理系统,可以实现容器集群的自动化部署、自动扩缩容、维护等功能。
我们可以用
k8s
去管理Docker
集群,即可以将Docker
看成k8s
内部使用的低级别组件。另外,k8s
不仅仅支持Docker
,还支持Rocket
,这是另一种容器技术。