husky 是一个用于在 Git 钩子(Git hooks)中运行脚本的工具,它允许你在代码提交、代码推送等 Git 事件发生时执行一些预定义的脚本任务。这可以帮助你在提交代码之前或之后执行一些自定义的操作,以确保代码的一致性、质量和规范性
Husky 的主要用于
- 代码规范检查: 在提交代码之前,使用 husky 运行代码规范检查工具,如 eslint、stylelint 等,确保代码的一致性、质量和规范性
- 运行单元测试: 在提交代码之前,使用 husky 运行单元测试,确保没有破坏现有的功能
- 自动化构建:在提交或推送之前运行构建脚本,去报新代码能正确的构建和打包
- 检查提交信息:在提交代码前,检查提交信息是否符合预定的规范,比如 Conventional Commits 规范
- 阻止不合规的提交: 如果在钩子中发现问题,husky 允许你阻止提交或推送,以确保只有合规的代码进入代码库
安装
在 git 仓库中,使用 husky-init
自动安装
- npm
- yarn
- pnpm
npx husky-init && npm install
yarn add husky --dev
pnpm dlx husky-init && pnpm install
husky-init
默认会做以下操作
- 在
package.json
中添加prepare
命令 - 创建一个
pre-commit
的 hook - 配置 git hooks 的路径
初始化完成后项目的根目录下会新建一个 .husky
文件夹,里面有一个文件 pre-commit
,用于提交(git commit)前执行的脚本。当然你也可以手动创建钩子文件,比如 pre-push
,下面这个脚本会在 git push 之前执行 lint 脚本
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npm run lint
配置代码检测
lint-staged 是一个用于在提交代码前运行预定的脚本(例如代码格式化、静态代码分析等)的工具。我们将它与 husky 结合使用,在提交代码前运行 eslint、stylelint、prettier 等代码检测工具
- npm
- yarn
- pnpm
npm install -D lint-staged
yarn add -D lint-staged
pnpm install -D lint-staged
lint-staged 使用 lilconfig 作为加载配置文件的工具,它支持一下配置文件
package.json
.lintstagedrc
.lintstagedrc.js
.lintstagedrc.cjs
.lintstagedrc.mjs
.lintstagedrc.json
.lintstagedrc.yaml
.lintstagedrc.yml
`lint-staged` in `package.json`
lint-staged 的配置文件需要导出一个对象,对对象的 key 是一个 glob 匹配模式,value 是一个需要执行的命令,命令可以跟参数。
{
"*.{js,jsx,ts,tsx}": "eslint",
"*.less": "stylelint",
"*": "prettier --write"
}
我们修改之前创建的 pre-commit
脚本,并在其中添加以下内容,此时执行 git commit 之前会先执行 lint 操作,lint 检查通过后才会提交代码。🚫💩
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no-install lint-staged
配置提交规范
在以下开源项目中,通常会配置代码提交规范,防止提交信息随便写,敷衍了事,比如 "update"
,"fix issue"
这种看了不知道改了啥的提交信息,
另外通过规范提交信息,也能够通过 git log --grep
快速过滤出相关提交,便于查找问题,为了规范提交 commit,便有了
commitlint。它可以检测我们的 commit 信息,如果不符合规范,则会阻止提交。
- npm
- yarn
- pnpm
npm install -D @commitlint/{cli,config-conventional}
yarn add -D @commitlint/{cli,config-conventional}
pnpm install -D @commitlint/{cli,config-conventional}
同样的 commitlint 也支持多种配置文件,在项目根目录下创建 commitlint.config.js
文件,我们便引入了 conventional commit 规范
module.exports = {
extends: ['@commitlint/config-conventional'],
};
在 husky 中添加 commit-msg
钩子,然后在其中调用 commitlint 进行检测。这样,我们在提交时,输入的提交信息不符合规范时,commitlint 会阻止提交,并给出提示。
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
npx --no -- commitlint --edit ${1}
conventional commit 规范**
规范规定了 commit 的格式,主要由以下部分组成,body 和 footer 都是可选的,header 信息不能省略。另外 header 中的 scope 是可选的,如果没有 scope,则可以省略。
<type>(<scope>): <subject>
// 空一行
<body>
// 空一行
<footer>
type
type 是必需的,用于说明 commit 的类别,只允许使用下面几个标识。
- build: 影响构建系统或外部依赖(例如 scopes: gulp, broccoli, npm)的修改
- ci: 影响 CI 配置文件和脚本的修改
- docs: 仅仅是文档的修改
- feat: 一个新功能
- fix: 修复一个 bug
- perf: 优化性能
- refactor: 代码重构
- style: 不影响代码含义的修改(空格、格式、缺少分号等)
- test: 添加缺失的测试或更正现有测试
- chore: 构建过程或辅助工具的变动
- revert: 回滚某个 commit
scope
scope 用于说明 commit 影响的范围,比如数据层、控制层、视图层等等,前端项目可能会是页面、数据层、组件、工具函数等。
subject
subject 是 commit 的简短描述,不超过 50 个字符,包含了本次修改的内容和原因。值得注意的是 subject 与冒号之间有一个空格。
例子
feat(parser): add ability to parse arrays
* add `parseArray` method
* add `parseObject` method
body
body 是对本次 commit 的详细描述,可以分成多行,包含了本次修改的动机和实现方法。
footer
footer 是对本次 commit 的关闭 issue 的描述,可以写多个 issue,也可以写关闭的 issue 的链接。
总结
以上就是前端工程化的基本流程,通过 husky、lint-staged、commitlint 等工具,可以实现代码检测、规范提交信息,提高代码质量,减少 bug。