git init
)npm init -y
)src/main.js
项目结构如图
.git 目录没有出现在 vscode 编辑器中是正常的。
在介绍 husky
之前,首先要理解什么是 hook(钩子),在前端 Vue 框架中提供了 beforCreated、created、beforeMounted、mounted 等函数、这些函数都是钩子,也常被称为‘生命周期钩子函数’,它们会在 Vue 实例化过程中有序地执行。
在 Git 中也存在一些钩子,其中较常用的有 pre-push、pre-commit
,其中 pre-commit
钩子会在 commit 前触发,pre-push
会在 push 前触发。(提示:所有钩子默认情况下是禁用的)
这些钩子可以用来干嘛?
比方我们可以利用pre-commit
钩子在 commit 时对代码先进行 eslint 检查,如果不合格就不给 commit,
不过使用 git 钩子稍微麻烦,于是就有了 husky
,它能让我们使用 git 钩子变得更加容易。
小插曲:关于“钩子”于”中间件“有什么区别,本人觉得没有区别,我甚至觉得钩子就是中间件,
因为无论是从作用、概念、实现上都能够作出合理的解释,如果你有更好的说法欢迎提出。
npm i hustky -D
npx husky install
npx husky add .husky/pre-commit
以上命令将会下载初始化 husky 并新增 pre-commit
钩子文件
下面只需在 pre-commit
文件自定义命令,即可在 commit 前触发,就这样,是不是很简单?
pre-commit
内容如下
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
echo "Hello,world"
下面 commit 时将会提前输出 ‘Hello,world’,如图
可以在根目录新增
.gitignore
文件让 git 忽略掉不需要提交的文件,避免影响学习测试。
prettier
工具可以在代码保存时进行格式化与检查(检查比较少用,不过剧情需要,这里还是演示一下)
我们可以在 commit 前让 pre-commit 执行 prettier 来检查代码格式是否合格,合格了才给 commit。
npm i prettier -D
2.2.1 在项目根目录新建 .prettierrc
配置文件,内容如下:
{
"tabWidth": 4, // 保存时为 4 个空格并以 tab 格式
"singleQuote": true, // 保存时为单引号
}
关于
.prettierrc
更多配置可参考官方文档,这里仅作为演示。
2.2.2 在 pakcage.json
新增脚本命令
"scripts": {
...
"prettier:check": "prettier --config .prettierrc --check \"src/**/*.{js,ts,css,html}\"",
...
},
2.2.3 在 husky/pre-commit
文件中将 echo “Hello,world” 修改为 npm run prettier:check
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run prettier:check
还记得 src/main.js
吗?现在我们对它修改如下:
function foo() {
console.log('Hello,foo') // 这里故意不缩进
}
效果如图
当然我们也可以让 prettier 除了检查外还能自动修复,这里用到 prettier 提供的另一个选项 --write
"scripts": {
...
"prettier:check": "prettier --config .prettierrc --check \"src/**/*.{js,ts,css,html}\" --write",
...
},
效果如图
可以看到 commit 提交成功,代码也自动帮我们格式化,如图:
function foo() {
console.log('Hello,foo'); // 多了 4 个空格
}
注意,虽然格式化了,但 main.js 文件状态并没有一起 commit 上去,仍然处于修改状态,如图:
也就是说 prettier 修复后,我们还要手动再次 git add . & git commit 上去,很明显,这不是我们想要的效果,这样只会增加无用的 commit 提交记录,为了解决这个问题,只需在 pre-commit
钩子新增以下命令即可
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# 新增 git add -A .
npm run prettier:check && git add -A .
现在我们重新对 main.js 进行格式错乱并 commit 提交,效果如图
一切正常
prettier 检查代码只是它的一部分,上面仅仅是配合 husky 作为演示,它更多的是用来代码保存自动格式化,怎么配置保存自动格式化网上有很多例子,这里不在讲述。
eslint
可以对代码进行约束规范,如果代码不符合规范则会在下面呈现一条~~~~
红色的波浪线,
相比于 prettier 的检查,eslint
更丰富更强大,因此 prettier 常用于保存自动格式化代码
, 而 eslint
作为代码规范检查
,两者可以结合使用。
npm i eslint -D
3.2.1 在根目录新建 .eslintrc.js
配置文件,内容如下
// eslint-disable-next-line no-undef
module.exports = {
"env": {
"browser": true,
"es2021": true
},
"extends": "eslint:recommended",
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
}
}
关于
.eslintrc.js
更多配置可参考官方文档,这里仅作为演示。
可以看到 main.js
出现了红色波浪线,因为 foo 未被任何地方引用。
3.4.1 在 package.json
新增脚本
"scripts": {
...
"eslint:check": "eslint src/*.js"
...
},
3.4.2 在 pre-commit
新增脚本
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# 注释
# npm run prettier:check && git add -A .
# 新增
npm run eslint:check
3.4.3 效果如图
可以看到 eslint 检测到 main.js 不符合规范并抛出错误,导致 commit 提交失败,
现在我们想让 eslint 自动修复这些报错只需在 packages.json
脚本中新增 --fix 选项即可
"scripts": {
...
"eslint:check": "eslint src/*.js --fix"
...
}
现在继续 commit ,你会看到问题依旧存在
难道 --fix 选项不生效?其实是生效的,只是 eslint 只会自动修复 .eslintrc.js
里对应的 rules
,其它的只能手动修复,像上面未引用的这种类型错误只能自己去处理,不信我们来验证一下:
首先在 .eslintrc.js
里面新增一条规则
// eslint-disable-next-line no-undef
module.exports = {
....
"rules": {
"comma-spacing": ["error", { "before": false, "after": true }],
}
}
该规则表示逗号之间必须要有空格,否则就会出现波浪线,如图
现在我们再次 commit
虽然 commit 提交失败,但可以看到 eslint 已经自动修复了逗号之间没有空格的问题,
剩下的只需手动把未引用的错误手动解决即可。
上面的插件都需要指定文件才能进行检查,比如 eslint
命令需要指定 src/*.js
,但这样会产生新的问题,如果 src
目录存在着大量的 .js 文件,那么每次执行 eslint
时都会对所有文件检查&修复,很明显除了对性能有影响外,还会影响同事以前写过的代码格式。
有没有办法能让这些工具只检查&修复我们修改过的文件就好呢? lint-staged
就可以做到。
lint-staged
能让这些插件只扫描暂存区的文件而不是全盘扫描,很明显,这就是我们想要的工具。
npm i lint-staged -D
4.2.1 在 package.json
新增 lint-staged
选项
"scripts": {
...
},
"lint-staged": {
"src/**/*.{js,jsx,ts,tsx,json,css,scss,md}": [
"eslint --fix"
]
},
4.2.2 在 pro-commit
新增命令
```sh
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
# 注释
# npm run prettier:check && git add -A .
# 注释
# npm run eslint:check
# 新增
npx lint-staged
现在假设 src 目录有一个 foo.js 文件,里面代码格式是错乱的
为了验证 lint-staged 会忽略掉除暂存区以外的文件,我们把这个 foo.js 先提交到本地仓库,
这里可以使用 git commit -m'test' -n
其中 -n 表示忽略 pre-commit 钩子,直接提交上去。
上面铺垫好了,下面开始验证 main.js ,代码格式如图
接下来 commit,效果如图
上面呈现一大串的东西不用担心,说明 lint-staged 正常运行,我们来看看 main.js 文件有没有发生变化,如图
可以看到 main.js 的逗号被修复并成功 commit 提交上去 ,且 foo.js 也不会受到影响,如图:
案例代码已上传到 github
完!
参考文献
https://github.com/typicode/husky/issues/949
https://medium.com/@anshul.kashyap03/set-up-git-hooks-with-husky-and-lint-staged-angular-example-a4d46e440ba5
https://laurieontech.com/posts/husky/
https://www.npmjs.com/package/husky