此文,仅是自己对过去的一个梳理,其中的 最佳实践 和 总结 并不一定 正确,请酌情阅读,也欢迎讨论。
在当前的公司也有差不多两年了,项目接触了差不多十几个,自己搭建的项目也有不少。纵观之前接手的项目,以及现在的新项目, 多多少少有点沉淀,写一写,记一记。
因为公司没有架构师,而且前前后后接触了几个项目组,每个项目组都有自己的风格。有的用 Vue, 有的用 React,还有一些老项目 用的 jQuery 那一套。
起因
因为接触的项目多了,做的事情自然有一些重复的,而于我个人来讲,最烦的事情莫过于同样的事情做三遍。
于此,记一记关于 工程项目 相关的思考。包括:
- 规范,包括项目结构规范,代码规范,前后端协议(接口)规范
- 项目编译,如 Webpack 等编译工具
- 持续集成,包括自动化测试,发布,回滚
规范
规范,一定是根据项目一直在变的,只是变动不会特别大,也不会特别频繁。
对规范目的的思考。我认为规范的目的是为了让一个项目,中途换一拨人来继续开发,也能很快上手。换句话是,也就是提高项目的维护性。
项目规范
基于自身的经历,捋一捋项目的规范。基本都在做业务相关的代码,所以,本篇所说的项目,也就是指业务型项目。
基于一个业务,本身包含基础的结构,例如无论使用的是什么框架,都会包含例如 api/utils/components
等通用的结构。在此之上,再添加其他目录结构。
对于 components
,我倾向于分为 components
和 biz-components
,前者表示通用组件(与业务无关),后者表示业务共享组件,主要用于复用业务逻辑。
除了基础结构,还可以添加 lib
目录,用于一些自己沉淀的无关业务的相关库,其作用和 utils
类似,只不过代码量比 utils
要大一些, 通常是一整块逻辑。utils
适合放一些小函数(代码不超过 30 行)。
另外的一些规范,可根据具体的框架和工具链进行调整。例如基于 Vite 工具链的开源模板 Vitesse。
其实具体的目录名称倒并不是特别的重要,重要的是,要有这些规范,且要根据项目,适当的增加规范。这样,写或者看代码的人,才知道对应的代码,放什么位置。
代码规范
个人认为,能避免错误的代码风格约束一定要有,至于其他的约束,最好配合代码格式化程序,例如 ESLint-Standard + ESLint-Prettier
这一块,主要目的有两个:
- 避免低级错误,在错误出现之前,就发现错误
- 格式化之后的代码,更好看
前后端之间的规范
这一块并不好定制,因为业务时常再变,有时候,甚至要直接调用第三方的服务,并不直接对接我们自己的后端。
这个时候,建议利用 axios
的 interceptors
,统一一下,相关的响应参数。
对于这一块规范,主要需要明确的是怎么处理错误码,以及错误信息。
项目编译
这两年,编译工具领域可谓是百花齐放,Vite,ESBuild, SWC, rome 这些工具一起冒了出来。 Webpack 也更新到 5.x,一堆破坏性的变更。总算是加上了一堆默认配置,可以开箱即用(但是感觉很鸡肋)。 简单介绍一下,这些工具
- Vite,一个新起之秀,基于 ESBuild + Rollup 的编译工具
- ESBuild,一个基于 Golang 的
js/ts
编译器,功能与Babel/Rollup
相同 - SWC,一个基于 Rust 的
js/ts
编译器,功能与Babel/Rollup
相同 - rome,一个新的前端工程工具链,目标是集成所有前端用到的工具,可以理解成,集成
Webpack/ESLint/Prettier
等这些工具的功能于一体,目前正在用Rust
重写(个人不是特别看好)
在这些工具出来之前,有一个开玩笑的职称叫 Webpack 配置工程师,可见 Webpack 的配置还是很复杂的。
在此,讲讲我与 Webpack 5.x 的故事,在 Vite 刚出来的时候,Webpack 也更新到了 5.x,当时公司的项目都还是用的 Webpack 4.x。 我的一个业余目标,就是想统一一下公司的打包工具,公司之前的项目,都是一个项目一个 Webpack 配置,就想写一个库支持打包所有的项目,就当练手。借此机会,研究了一下 Webpack 5.x 的并写了一个 xxx-compile
(脱敏处理一下) 的内部工具,开箱支持 TS/Vue/React
,以及热更新。
说着也巧,正是在我差不多写完这个库之后,Vite 1.0 出来了!之后,开始接触 Vite,真香!今年 10 月左右的时候,换了一个项目组,接手了几个新项目, 看到是新项目,接手的第一件事情,就是把项目从 Webpack 切换到 Vite。真香!
从我的经历来看,Vite 的配置相比 Webpack 要简单很多。
但即使是这样,我也更倾向于使用类似 Parcel 这样的一键打包工具。为什么没选 Parcel 呢?因为定制天花板不是特别高。
基于此,我更倾向于,公司基于 Webpack 或者 Vite 这样的工具,自己封装一个编译工具,自己根据规范抽象一套配置。 封装的编译工具也能根据规范去实现对应的功能,这样就几乎不需要配置项。
为什么要抽象一套配置,而不是基于已有的 Webpack 配置或者 Vite 配置。支持抽象一套配置的好处有两点:
持续集成
一个项目一定要有一个自动化相关的辅助系统,例如 Github Actions
必要的相关集成:
- 自动化测试
- 测试环境自动部署
- 发布控制
- 回滚控制
可选的集成
- 金丝雀发布
虽然上面说的是必要的,但其实也可以都没有。毕竟前端的发布,都是一些静态资源,并没有后端那么多需要注意的点。
测试代码也可以直接在本地跑一遍。如果能集成在一起,当然是最好的。
关于这一块,之后整理一个基于 Docker 搭建的一系列内网服务,再仔细记录一下。