浅析前端工程化CodeLint:使用 husky+lint-staged+commitlint 规范团队代码格式及提交规范
Code Lint是前端工程化中的一个重要环节,它可以帮助我们在部署代码到生产环境之前及时发现错误并纠正它们,也可以规范我们的编码习惯,让团队的代码风格保持统一。
Code Lint的工作原理是借助一些lint工具对代码进行静态分析,并在合适的时机触发校验,提示错误。
在一个团队项目中,代码风格不统一,会大大的降低可读性,也会给后期的维护增加时间成本。如果代码风格统一、代码提交信息也简单明了,那么在后期协作以及处理bug时可以达到事半功倍的效果,所以就需要在我们使用git提交时校验eslint和提交信息的格式问题。需要用到的插件 husky、lint-staged、commitlint。
一、有哪些 lint?
随着nodejs和前端工程化的发展,前端圈内产出了很多成熟的Lint工具,主要包括:
eslint 规范并校验 ECMAScript/JavaScript code的编写
tslint 规范并校验 TypeScript code的编写
stylelint 规范并校验css/scss/less code的编写
commitlint 负责校验commit msg是否符合规范
prettier 或 beautifyjs 统一代码排版格式
除此之外,我们还需要一些辅助的工具:
husky 能够监听git hooks的nodejs包,让nodejs开发者处理git hooks任务变得更加容易
lint-staged 可以将git“已暂存(staged)”的文件作为参数传入你要执行的shell script之中
比如集成 commit lint:在小的团队里,可能我们更注重的是业务产出,并不在乎这些细节。随着团队的壮大,commit msg 规范化至关重要,他意味着我们是否清楚自己和同事对代码干了什么,在代码排错、回滚时起到了关键性作用。本着“工具比人更可靠”的原则,我们期望通过在项目中集成一些工具,从而实现在执行git commit -m 'msg'时能够自动的对msg内容进行校验,无需额外执行其他命令,husky和 commitlint恰好能解决我们这个痛点。
二、理解 git hooks 和 husky
先要介绍一下git hooks,顾名思义hooks为“钩子”之意,它是“发布订阅模式”的一种实现,和前端中的DOM事件(click、hover等)相似,Git也预先定义了一些“事件钩子”如“commit-msg”、“pre-commit”等,当我们执行对应的Git操作时会触发它们,从而通知订阅该事件的shell script文件处理我们要进行的任务,这些shell脚本文件存放在项目根目录下的.git/hooks 目录中。
我们可以通过编写这些shell script文件定制我们的校验任务,但前端工程师大多对linux/windows shell并不擅长,这和我们平时的工作重心有关,因此我们通过编写git hooks脚本来优化前端工作流的这条道路十分艰难。Nodejs改变了这一切,它让JavaScript拥有了控制“操作系统”的能力,你只需要安装nodejs包 husky,它会帮我们自动生成.git/hooks目录下的shell script,我们便可以很轻松的使用更熟悉的Nodejs处理git hooks任务,而无需关注shell script的实现细节。
// 执行下面命令, 在开发环境中安装husky,如下所示:
npm install husky --save-dev
// 在项目根目录下package.json文件中添加如下配置,并在hooks字段下添加git hooks监听任务配置, 如下:
// 这是NPM原生支持的脚本执行定义,当执行“npm run 脚本名”时执行
"scripts": {
"test": "node test.js"
},
// 这是husky扩展的脚本执行的定义方式,当对应git hooks触发时执行
"husky": {
"hooks": {
// 可以执行一个js文件,将控制权转移给我们更熟悉的nodejs
"pre-commit": "node heihei.js",
// 也可以调用其他脚本或者执行一段原生shell命令
"commit-msg": "npm run test && echo succeed"
}
}
// 上面的配置只作为测试例子之用,无需真正集成到项目中,大家可以先写一个小demo尝试一下,加深一下对git hooks和husky的理解。
三、husky
husky 是一个为 git 客户端增加 hook 的工具。安装成功后,它会自动在仓库中的 .git/hooks/
目录下增加相应的钩子;比如本项目种需要使用的 commit-msg
、 pre-commit
钩子就会在你执行 git commit
的触发。
// 先安装最新的husky。
npm install husky --save-dev
// 启动git钩子。启用后就可以看到项目根目录下生成了.husky文件夹。
npx husky install
// 然后依次生成我们需要的 git hook。
// 引号中的内容是需要执行的脚本,可以在对应的官网中找到,下面会给出地址。
npx husky add .husky/pre-commit 'lint-staged'
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'
生成后就可以在.husky/下看到我们生成的两个git hook,commit-msg和 pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx --no -- commitlint --edit $1
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"
npx lint-staged
四、lint-staged
每次检查代码我们不需要检查全项目的文件,那样只会增加时间成本,这时候就需要用到 lint-staged
,一个仅仅过滤出 Git 代码暂存区文件(被 git add 的文件)的工具。
npm install lint-staged -D
五、commitlint
正如官方文档中所言,commitlint
帮助你的团队遵守commit约定,检查你的提交消息是否符合传统的提交格式。
npm install -D @commitlint/cli @commitlint/config-conventional
随后要添加配置文件,文件的格式可以是 commitlint.config.js、.commitlintrc.js、.commitlintrc、 .commitlintrc.json、 .commitlintrc.yml文件,或 package.json中的 commitlint字段中定义配置。可以自己创建,也可以按照官网的方式使用下面这行代码生成,这需要在项目的git命令行中操作(通常是在项目目录中使用右键选择Git Bash Here)
echo "module.exports = { extends: ['@commitlint/config-conventional'] };" > commitlint.config.js
生成后就可以在commitlint.config.js
文件中,制定提交信息的规范,相关配置项可以参考官方文档:https://commitlint.js.org/#/reference-rules?id=rules
这里暂时只制定了基础的规范,只能使用feat、fix、docs、style、refactor、test、revert这7中格式进行提交。
/**
* rule由key和配置数组组成
* 如:'key:[0, 'always', 72]'
* 数组中第一位为level,可选0,1,2,0为disable,1为warning,2为error,
* 第二位为是否应用,可选always|never,
* 第三位该rule的值
*
* 提交信息可自定义规范
* feat:新功能(feature)
fix:修补bug
docs:文档(documentation)
style: 格式(不影响代码运行的变动)
refactor:重构(即不是新增功能,也不是修改bug的代码变动)
test:增加测试
chore:构建过程或辅助工具的变动
* **/
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', [
"feat", "fix", "docs", "style", "refactor", "test", "revert"
]]
}
}
// 写在 package.json中,格式为:
"commitlint": {
"rules": {
"type-enum": [2, 'always', ["feat", "fix", "docs", "style", "refactor", "test", "revert"]]
}
}
六、配置项
需要的插件都安装成功后,就可以在 package.json 中配置 pre-commit 钩子函数的执行内容。
这里对lint-staged的配置是:对src下的所有.js和.vue文件先代码检查,然后代码修复,最后添加至缓存区。此修复只会修复一些简单的eslint格式错误,修复不了的格式错误,就会报错提交失败。随后在校验提交信息的格式。
"husky": {
"hooks": {
"commit-msg": "commitlint -e $HUSKY_GIT_PARAMS",
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"src/**/*.{js,vue}": [
"eslint --fix --ext .js,.vue",
"git add"
]
}
这样才 commit 之前就会自动检测代码格式和 git commit 的提交规范了。还有很多其他如 StyleLint 规范等的使用,有需要的时候就可以自己搜索实践吧。