在写这篇文章前,我有去掘金和知乎上看别人对前端工程化的理解,各自各样的都有,但是没有一篇跟我想的一样。不知道我理解的是不是错的,总之我想把我此时此刻的想法记录下来,等多年以后见识多了再回头来验证。
前端工程化的由来
随着项目做的越来越多,你会发现其实工作中存在着很多重复的工作。于是你就开始不断的做封装,提升代码复用性,降低重复的工作。
封装的程度可大可小,大致分几个层次:
- 函数封装、代码逻辑封装、组件封装
- 通用组件或通用工具类封装
- 脚手架工具、模板生成工具
- 项目管理系统
但即使做到第 4 阶段还是不够,这只是在开发阶段提供便利,其他方面并没有得到提升,比如发布、部署也是一个繁琐的过程。随着前端技术逐渐成熟,整个前端项目体系不断完善,由此形成了前端工程化体系。
前端工程化是什么
前端工程化是软件工程的一种实现,是为了提高效率和降低成本而存在的。前端工程化不是单从开发角度考虑,而是为整个项目生命周期各个阶段考虑。最近很流行的一张 DevOps 闭环图很能体现整个项目生命周期:
dev
开发阶段
plan
制定计划code
编码build
构建test
测试
ops
运维阶段
release
发布deploy
部署operate
运营monitor
监控
监控通常是为了完善系统,所以监控完下一步就是制定计划,形成闭环。前端工程化要做的就是让各个阶段能够更快的进行。
从前端角度去看,以上那些阶段将转化为:设计、开发、测试、部署、监控。
设计
处于 plan
阶段,在接到需求后进行需求分析、熟悉业务、任务拆解。对于新项目,还需进行架构设计。
架构设计
架构设计通常是根据业务场景做做技术栈选型、路由设计、项目结构设计。像业界一些热门词比如中台、微前端之类的可以在这阶段考虑要不要引入,不过要记住,任何技术的引入都需要充分考虑业务场景。任何一项技术架构都没有厉不厉害、好不好用之说,只有合不合适的问题。
前端工程化在架构设计上的体现就是前端脚手架,就像 Vue 的 @vue/cli
一样,只要在终端运行命令行,项目结构就帮你搭建好了。然后再通过问答的方式,选出你想要的技术栈或者业务方案。就这样一套架构设计就完成了。
当然仅仅这样是不够的,@vue/cli
只会选出一些常用的技术栈和 Vue 相关的技术栈。公司都会自己沉淀一些技术,比如常用工具类和组件库。实际项目开发,也不仅仅是只有技术问题,还会沉淀一些业务方案。
总的来说,公司应该要有属于自己的一套脚手架,将多年沉淀的技术方案和业务方案集成在一套脚手架里。这样在架构设计阶段,就是一条命令行和几个问答就能解决了。至于如何有效的做技术沉淀就是另外一个问题,还有开发一个脚手架并不容易,最好是基于第三方的做封装才能有效避开很多坑。
需求分析
理论上每次有新的需求都应该做需求分析,至于如何做需求分析,我还没找到有什么有效的方案。但至少要做到熟悉需求、熟悉业务,了解为什么会有这样需求出现。只有从业务的角度看需求,你才能预知未来可能会做怎样的需求变动,在代码上就能提前做防患。
在这阶段还要有个重要的环节,就是做任务拆解。很多人拿到原型后,就从头到尾一个一个页面做下去。又或者根据业务流程顺序,一个一个页面做下去。大多数人是以页面为单位做开发,这个在以往的 JQuery 确实只能这样,但在这组件化的时代,应该有更有效的方式。
以页面为单位做开发会有个现场,就是容易出现重复造轮子的现象,A 页面做了,B 页面又做了一遍。要是不同人开发,就是开发两遍。要是同一个人开发,很多人就开启 CV 大法,复制粘贴改一改就完事。不仅浪费时间,代码质量也下降,更重要的是你又错失了一个沉淀技术的机会。经常听到有人说 “现在项目那么赶,先复制粘贴下,后面有空再来优化代码”,可结果能有几个人会改,下一个任务还在等着你做。这种现象的问题根据是任务分配不合理造成的,如果你的任务就只是封装这个组件,而不是做这个页面,你肯定会好好对待。
一块需求的开发,应该是包含一个任务叫任务拆解。这个任务就负责分析各个页面的异同点,和根据业务需求预知后续可能出现页面。然后拆分为组件开发、逻辑开发、页面开发,这边的页面开发应该是分析完的不可拆分的页面,或者各个组件和逻辑的组合拼凑任务。
开发
处于 code
阶段,是写代码的阶段,写出的代码被称为开发环境的代码。这阶段主要注重的是如何更快的完成系统开发,也就是提升开发效率。在实际项目开发过程中,时常会因为需求变更而需求修改原来的代码,所以这阶段又注重代码可维护性。
提高开发效率
这方面在前端工程化里面主要做两件事情:编译、预览,其他都是特定场合或特定技术栈做的事。
- 编译:ES6+ 代码转为 ES5 代码,或者引入一些插件做代码转化。
- 预览:让项目在浏览器上跑起来,页面热更新处理。
通常都会借助一些构建工具来完成,比如 Webpack、rollup、vite。每一种构建工具都有各自的优势,具体使用哪种应该是由业务场景决定的。选择更合适的构建工具主要是为了提升编译速度,为了能够更快看到页面效果。
提高维护性
这方面在前端工程化的体现就是规范化:代码规范化、接口规范化、文件结构规范化等等。用规范化来让所有开发者保持相同的编码风格和组织方式,这样一来查找文件和修改代码就会更加迅速。最常见的就是使用 ESLint 做代码规范化。强制让所有人的代码风格保持一致。
测试
这阶段包含 code
和 test
阶段,这边的测试不是测试工程师做的测试工作,而是前端做单元测试和集成测试。在前端工程里,test
可以在 build
之前执行,针对于开发环境的代码做测试。用于测试的代码也需要编写,所以也包含在 code
里。
很多公司在这个阶段是采用人工测试,人工测试通常是不靠谱的,容易漏掉一些业务细节。使用单元测试和集成测试就会逼着你编写测试方案,考虑得会更加全面。最重要的是能保留当前测试方案,将来需求变更或者重构代码时才不容易遗漏需求,有效降低 bug 量。
部署
这是 build
、release
、deploy
综合起来的阶段。到这阶段就说明系统现阶段的功能已经开发完成了,下一步就是发给测试工程师做测试工作。测试工程师通常会有自己的测试环境,会将系统部署到测试环境才能进行测试。所以这个阶段就是完成系统构建、软件包发布、将包部署在测试环境上。
前端工程化在这方面已经有比较完善的方案了,就是自动化部署。例如 GitHub Actions ,使用 Github 管理项目,执行 git push --tags
推送源码上去就会自动帮你执行这一系列部署操作。公司内部项目可以使用 GitLab 也有类似的功能。
部署之前有个构建工作,将代码构建成生产环境的软件包。这过程与开发类似,需要借助 Webpack 之类的构建工具完成。与开发不同的是,开发注重的是编译构建速度,而这阶段注重的是代码体积尽可能小。为了让最终的软件包体积尽可能小,在设计阶段的技术选型环节就要考虑好。
监控
这个现在还没什么想法,后续补充!
总结
前端工程化包含很多阶段,每个阶段都是作用于项目,所以通常会在 npm scripts 上体现:
{
"scripts": {
"start": "webpack-dev-server --mode=development",
"build": "webpack --mode=production",
"lint": "eslint --ext js,vue src",
"test": "jest",
"deploy": "git push --tags"
}
}
你也许会看到这样的 npm scripts ,也许会更多。这边不讨论如何定义 npm scripts ,这边想说的是每一个阶段的实现,都是通过执行一条条命令行来触发,创建项目也是通过命令行创建。所以前端工程化的都是建立在 NodeJS 平台和 npm 体系,命令行工具的开发就成为了前端工程化的基础。后续有机会再写在命令行工具的相关文章。
以上是我的一些拙见,如果有哪个地方说得不对的话,欢迎来提 issue。