在 《JS 模块化》系列开篇中,曾提到前端技术的发展不断融入很多后端思想,形成前端的“四个现代化”:工程化、模块化、规范化、流程化。在该系列文章中已详细介绍了模块化的发展及四种模块化规范。本文简单聊聊规范化中的 git 规范。
1 规范化
在企业级开发中,“一千个读者有一千个哈姆雷特”是很常见的事,每个程序员对技术的理解、视角和掌握程度参差不齐,导致编写的代码五花八门。规范化包括很多,我在企业实践中重点关注两个方面:代码规范 和 git 提交规范。
代码规范最基础的是代码格式,不同的代码格式虽然运行起来没有问题,但代码超级难看,代码乱七八糟、一堆 warning,虽然不影响运行,但看着太恶心,就像下面的情形:
- 估计是为了节省纸张,空格全省略,代码全挤在一起:
const a=b+c
const fn=()=>{}
fn(){}
for(let i=0; i<10; i++){}
- 单引号、双引号混合使用,上一行用单引号,下一行偏要用双引号;
- 上一行加分号,后一行省略分号;
- 定义了一些从没有使用的变量;
- 分支判断中只有一句话坚决不写花括号;
- ......
我不能说上面的风格是错误的(写代码就像玩音乐一样,不能说绝对的对错,只是理解不同罢了),无论怎么写,至少一个团队还是应该保证统一的风格吧。于是咱们就使用了 .editorconfig 和 eslint。
.editorconfig 对编辑器的基本格式做了限制,但比较粗糙;eslint 就进行了详细的约束。无论选择 standard 、airbnb、prettier 任何一种,都是为了强制团队使用统一的代码风格。
在 《创建 vite vue3 项目》一文中已讨论了如何在基于 vite 的 vue3 项目中如何整合 eslint。
本文重点讨论 git 提交规范。
2 git 提交规范
大家应该都是使用 git 管理代码吧?如果你在企业还是使用 SVN 管理代码,那可以赶快跑路了。git 提交代码使用 git commit -m '描述' 命令。但描述信息很多情况下都是随意填写,git 提交规范就是针对这个描述信息的约束。
2.1 Angular 规范
Angular 团队规范是目前使用较多的 git 提交规范 —— 约定式提交。规范要求提交的描述信息格式为:
<type>[optional scope]: <description>
[optional body]
[optional footer(s)]
含有 optional 表示可选,故必填的内容是 type 和 description。
type 表示这次提交的类型,包括如下值:
type | 含义 |
---|---|
feat | 新功能 |
fix | 修复 |
docs | 文档变更 |
style | 代码格式(不影响代码运行) |
refactor | 重构(不增加新功能,也不是修改 bug) |
perf | 性能优化 |
test | 添加测试 |
chore | 修改构建过程或辅助工具 |
revert | 回退 |
build | 打包 |
例如,实现了一个修改用户列表功能,此时提交代码使用如下命令:
git commit -m 'feat: 实现用户列表'
修改了 vite.config.ts 的配置,压缩打包文件:
git commit -m 'chore: 修改vite生产配置'
2.2 Commitizen
确定了git 提交时描述信息的规范,那如何让人遵守执行呢?首先需要让开发同事知道提交信息的内容,此时可以使用工具 commitizen 来完成。commitizen 是一个 git 提交规范化的工具,提供了 git cz 命令来代替传统的 git commit 命令。使用 git cz 来提交代码,commitizen 会一步步提示输入的字段,并提交所填写的必需字段。换句话说,使用 git cz 命令,底层最后会执行 git commit,但在执行 git commit 前,会校验描述信息是否符合规范。如果不符合规范,则不会执行 git commit,提交失败。
- 全局安装 commitizen
yarn global add commitizen
- 在工程中安装 cz-conventional-changelog
yarn add cz-conventional-changelog -D
- 在工程中初始化 commitizen 的约定式提交:
commitizen init cz-conventional-changelog --yarn --dev --exact
执行完该命令,package.json 文件中会自动生成如下配置:
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
}
完成上述步骤后,便可以使用 git cz 命令来提交代码了。
添加需要提交的文件,添加文件后执行 git cz 命令,提示如下:
使用上下键选择提交的类型,按照提示输入相关内容或必填内容即可完成提交。
3 git hooks
上面实现了 Git 提交规范,但仍然有不听话的同学会使用 git commit,如此一来提交信息依旧是乱七八糟的,此时便需要使用 git hooks 了。
3.1 什么是 git hooks
hooks 意思是“钩子”,也就是在执行某个操作之前或之后要做的事。git hooks 就是 git 操作的钩子,在 git 执行某个操作之前或之后要做的事,如 git 提交后、提交后、合并前、合并后、rebase前、rebase后等。在这里需要重点关注的 git 钩子有两个:
- pre-commit
pre-commit 是 git commit 执行前的钩子,会在获取提交描述信息且提交前被调用,根据该钩子决定是否拒绝提交。可以在这个钩子中对代码进行 eslint 检查。
- commit-msg
commit-msg 也是 git commit 执行前的钩子,用来规范化标准格式,根据标准和提交的描述信息决定是否拒绝提交。可以在这个钩子中检查提价信息是否符合规范。
3.2 commitlint 和 husky
理解 git hooks 后,就是如何在工程中引入上述钩子。此时需要使用到 husky 和 commitlint。两者结合起来可以在提交的描述信息不规范时会导致提交失败,并提示错误。首先安装配置 commitlint。
- 安装 husky 和 commitlink 相关依赖:
yarn add husky @commitlint/cli @commitlint/config-conventional -D
- 在项目根目录创建 commitlint.config.cjs 配置文件:
module.exports = {
extends: [
'@commitlint/config-conventional'
]
}
- 初始化 husky
npx husky install
执行完成后,项目根目录会自动生成一个 .husky 文件夹。
3.3 pre-commit 和 commit-msg 钩子
接下来需要使用 lint-staged 对git 暂存区(git add . 的内容)文件进行 eslint 检查。
- 安装 lint-staged
yarn add lint-staged -D
- 在 package.json 中添加 scripts:
"scripts": {
...
"lint": "eslint \"src/**/*.{js,ts,vue,jsx,tsx}\" --fix"
},
- 在 package.json 添加 lint-staged 配置:
{
.....
"lint-staged": {
"*.{js,ts,jsx,tsx,vue}": [
"npm run lint"
]
}
}
- 分别执行下列命令,为 husky 添加 commit 前的 hook,让其执行 eslint 和 commitlint :
npx husky add .husky/pre-commit 'npx lint-staged'
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
执行完该命令后,会自动在 .husky/ 目录下生成 pre-commi 文件和 commit-msg 文件。
pre-commit 文件内容如下:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx lint-staged
commit-msg 文件内容如下:
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no-install commitlint --edit ""
3.4 测试
到此为止便完成了配置,可以按如下步骤进行测试:
git add .
git commit -m '测试提交'
控制台会出现如下错误提示:
使用 git cz 命令重新提交,便可以成功提交。
各位还可以弄点 eslint 错误再提交试试效果。