如何在前端项目中配置 Git 提交校验,实现:
- pre-commit:提交前用 lint-staged 只对暂存文件做 ESLint/Prettier 校验和格式化
- commit-msg:用 commitlint 校验提交信息(commit message)是否符合规范
目录
- 工具职责说明
- 安装依赖
- 初始化 husky
- 配置 lint-staged(pre-commit)
- 配置 commitlint(commit-msg)
- 提交信息规范说明
- 完整文件清单
- 验证流程
- 常见问题 FAQ
1. 工具职责说明
| 工具 | 作用 | 触发时机 |
|---|---|---|
| husky | 管理 Git 钩子(hooks),让提交时能自动触发脚本 | Git 操作时 |
| lint-staged | 只对 Git 暂存区(staged)的文件运行 lint/格式化,避免全量扫描 |
pre-commit 钩子 |
| commitlint | 校验 commit message 是否符合约定式提交规范 |
commit-msg 钩子 |
整体流程:
git commit
│
├── pre-commit 钩子 → lint-staged → ESLint / Prettier(只处理暂存文件)
│ └── 校验失败 → 中断提交
│
└── commit-msg 钩子 → commitlint 校验提交信息
└── 不符合规范 → 中断提交
2. 安装依赖
根据你使用的包管理器选择对应命令。
npm
npm install --save-dev husky lint-staged @commitlint/cli @commitlint/config-conventional
pnpm
pnpm add -D husky lint-staged @commitlint/cli @commitlint/config-conventional
yarn
yarn add -D husky lint-staged @commitlint/cli @commitlint/config-conventional
若项目还没有 ESLint / Prettier,按需补充安装:
npm install --save-dev eslint prettier
3. 初始化 husky
以下以 husky v9+(当前主流版本)为例。v9 的用法比旧版更简洁。
3.1 执行初始化
npx husky init
该命令会:
- 创建
.husky/目录 - 生成一个示例
.husky/pre-commit文件 - 在
package.json的scripts中自动添加"prepare": "husky"
prepare 脚本的作用:其他人 npm install 时会自动执行,确保 husky 钩子被正确安装。
3.2 确认 package.json
{
"scripts": {
"prepare": "husky"
}
}
如果
npx husky init没有自动写入,请手动添加,然后执行一次npm run prepare。
4. 配置 lint-staged(pre-commit)
4.1 编写 lint-staged 配置
在项目根目录新建 .lintstagedrc.json(或写在 package.json 里,二选一)。
方式 A:独立文件 .lintstagedrc.json(推荐)
{
"*.{js,jsx,ts,tsx,vue}": [
"eslint --fix",
"prettier --write"
],
"*.{css,scss,less,html,json,md}": [
"prettier --write"
]
}
方式 B:写在 package.json
{
"lint-staged": {
"*.{js,jsx,ts,tsx,vue}": [
"eslint --fix",
"prettier --write"
],
"*.{css,scss,less,html,json,md}": [
"prettier --write"
]
}
}
说明:
- 键是文件匹配 glob,值是要执行的命令数组,按顺序执行。
-
eslint --fix会自动修复可修复的问题;无法自动修复的错误会中断提交。 - lint-staged 只处理
git add过的文件,修复后会自动重新git add。
4.2 配置 pre-commit 钩子
编辑 .husky/pre-commit,内容如下:
npx lint-staged
husky v9+ 不再需要旧版的
#!/bin/sh和. "$(dirname -- "$0")/_/husky.sh"样板代码,直接写命令即可。
确保该文件有可执行权限(macOS/Linux):
chmod +x .husky/pre-commit
5. 配置 commitlint(commit-msg)
5.1 编写 commitlint 配置
在项目根目录新建 commitlint.config.js:
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
// 提交类型枚举,可按需增删
'type-enum': [
2,
'always',
[
'feat', // 新功能
'fix', // 修复 bug
'docs', // 文档变更
'style', // 代码格式(不影响功能,例如空格、分号)
'refactor', // 重构(既不是新增功能,也不是修 bug)
'perf', // 性能优化
'test', // 增加测试
'build', // 构建系统或依赖变更
'ci', // CI 配置变更
'chore', // 其他杂项(不修改 src 或测试)
'revert' // 回滚提交
]
],
'subject-empty': [2, 'never'], // subject 不能为空
'type-empty': [2, 'never'], // type 不能为空
'subject-full-stop': [2, 'never', '.'], // subject 结尾不加句号
'header-max-length': [2, 'always', 100] // header 最长 100 字符
}
};
若项目是 ESM(
package.json中"type": "module"),请将文件命名为commitlint.config.cjs,或改用export default {}语法。
5.2 配置 commit-msg 钩子
新建 .husky/commit-msg,内容如下:
npx --no-install commitlint --edit "$1"
-
$1是 Git 传入的提交信息临时文件路径。 -
--no-install避免运行时临时下载。
确保可执行权限:
chmod +x .husky/commit-msg
6. 提交信息规范说明
采用 Conventional Commits 约定式提交规范。
6.1 格式
<type>(<scope>): <subject>
<body>
<footer>
- type(必填):提交类型,见上方枚举
-
scope(可选):影响范围,如
login、api、user - subject(必填):简短描述,不超过 100 字符,结尾不加句号
- body(可选):详细描述
-
footer(可选):关联 issue 或破坏性变更说明,如
Closes #123
6.2 示例
✅ 正确示例:
feat(login): 新增手机号验证码登录
fix(api): 修复用户列表分页参数丢失问题
docs: 更新 README 安装说明
refactor(order): 拆分订单结算逻辑
perf: 优化首页图片懒加载
chore: 升级 vite 到 5.0
❌ 错误示例:
更新代码 → 缺少 type
feat 新增功能 → type 后缺少冒号和空格
Fix: bug. → 结尾多了句号,且大小写不符
6.3 破坏性变更
feat(api): 重构用户接口返回结构
BREAKING CHANGE: user 接口不再返回 token 字段,需从 auth 接口获取
7. 完整文件清单
配置完成后,项目应包含以下文件:
项目根目录/
├── .husky/
│ ├── pre-commit # 内容:npx lint-staged
│ └── commit-msg # 内容:npx --no-install commitlint --edit "$1"
├── .lintstagedrc.json # lint-staged 配置
├── commitlint.config.js # commitlint 配置
└── package.json # 含 prepare 脚本和相关依赖
package.json 关键部分:
{
"scripts": {
"prepare": "husky"
},
"devDependencies": {
"@commitlint/cli": "^19.0.0",
"@commitlint/config-conventional": "^19.0.0",
"husky": "^9.0.0",
"lint-staged": "^15.0.0"
}
}
8. 验证流程
8.1 验证 pre-commit
故意在某个 .js 文件里写一段不符合 ESLint 规则的代码:
const a = 1 // 假设规则要求分号
执行提交:
git add .
git commit -m "test: 验证 pre-commit"
预期:lint-staged 触发,eslint --fix 尝试修复;若有无法修复的错误,提交被中断。
8.2 验证 commit-msg
用不规范的信息提交:
git commit -m "随便写的提交信息"
预期:commitlint 报错并中断提交,提示 type 缺失。
再用规范信息提交:
git commit -m "feat: 完成提交校验配置"
预期:校验通过,提交成功。