Commitlint + Husky + lint-staged 工程化配置:让Commit规范+代码校验自动化落地
上一篇我们详细拆解了 Conventional Commits 约定式提交规范,明确了“如何写规范的Commit信息”。但实际团队协作中,仅靠人工记忆和自觉,很难保证每一次提交都符合规范——总会有开发者忽略格式、写错type,甚至提交不符合代码规范的代码,导致代码仓库混乱、协作效率下降。
这时候就需要一套工程化工具链,将“规范约束”自动化:用 Commitlint 校验Commit信息、用 Husky 拦截不规范提交、用 lint-staged 只校验本次提交的代码,三者结合,实现“提交前自动校验、不规范则拦截”,彻底解决规范落地难的问题。
本文将从「工具作用拆解」「环境准备」「分步配置」「异常排查」「实战优化」五个维度,手把手教你配置这套工程化工具,无论是个人项目还是团队协作,都能直接照搬使用,让规范落地更轻松。
一、先搞懂:三个工具各自负责什么?
在开始配置前,先明确 Commitlint、Husky、lint-staged 三者的核心作用,避免配置时混淆,理解它们的协同逻辑:
1. Commitlint:校验Commit信息的“质检员”
核心作用:检查你提交的 Commit 信息(如 feat(user): 新增注册功能)是否符合 Conventional Commits 规范,比如 type 是否正确、格式是否达标、description 是否符合要求。
没有它,开发者可能会提交 fix: 改bug「模糊描述」、Feat: 新增功能「type大写」等不规范信息,无法实现Commit信息的语义化。
关键依赖:@commitlint/cli(核心校验工具)、@commitlint/config-conventional(遵循官方Conventional Commits规范的校验规则)。
2. Husky:Git钩子的“执行者”
核心作用:Git 本身提供了很多钩子(如提交前、提交信息校验前、推送前等),Husky 可以让我们更方便地配置这些钩子,在特定时机执行自定义脚本(比如校验Commit信息、校验代码格式)。
我们主要用到它的commit-msg 钩子(校验Commit信息)和 pre-commit 钩子(校验代码格式):
commit-msg:在开发者输入Commit信息后、提交完成前,执行Commitlint校验,不通过则拦截提交;pre-commit:在提交代码前,执行代码校验(如ESLint、Prettier),不通过则拦截提交。
没有它,Commitlint 和 lint-staged 无法和Git提交流程关联,只能手动执行校验,无法实现“自动拦截”。
3. lint-staged:代码校验的“高效过滤器”
核心作用:只对「本次提交的代码文件」进行校验(如ESLint、Prettier格式化),而不是校验整个项目的所有代码。
为什么需要它?如果项目较大,每次提交都校验所有代码,会消耗大量时间;而 lint-staged 只处理暂存区(git add 后的文件)的代码,既高效,又能避免误改其他未提交的代码,提升开发效率。
它常和 ESLint、Prettier 配合使用,确保提交的代码符合项目代码规范。
三者协同逻辑(关键)
开发者执行 git commit -m "xxx" → Husky 触发 pre-commit 钩子 → lint-staged 校验本次提交的代码(ESLint/Prettier)→ 校验通过后,Husky 触发 commit-msg 钩子 → Commitlint 校验Commit信息 → 校验通过,完成提交;任意一步失败,拦截提交,提示开发者修改。
二、环境准备:前置条件与依赖说明
在配置前,确保你的项目满足以下前置条件,避免配置过程中出现异常:
2.1 前置条件
- 项目已初始化 Git(执行过
git init),且有至少一次提交记录(可选,部分Husky版本需要); - 项目已初始化 npm/yarn/pnpm(执行过
npm init -y),有package.json文件; - (可选)项目已配置 ESLint 和 Prettier(如果需要校验代码格式,否则可只配置Commit信息校验)。
2.2 依赖版本说明(避坑关键)
不同版本的工具可能存在兼容性问题,本文使用目前稳定且常用的版本,建议直接照搬,避免版本冲突:
- Husky:8.x 版本(目前最新稳定版,配置方式和7.x有差异,本文重点讲8.x);
- Commitlint:17.x 版本;
- lint-staged:13.x 版本;
- ESLint:8.x 版本(若需代码校验);
- Prettier:2.x 版本(若需代码格式化)。
三、分步配置:从0到1完成自动化校验
以下配置步骤基于 npm(yarn/pnpm 可对应替换命令,如 yarn add 替换 npm install),全程实操,每一步都有详细说明和代码示例,新手也能轻松跟上。
第一步:安装依赖(一次性安装所有核心依赖)
执行以下命令,安装 Commitlint、Husky、lint-staged 核心依赖,以及 ESLint、Prettier(若需代码校验):
# 核心依赖(必装)
npm install --save-dev @commitlint/cli @commitlint/config-conventional husky lint-staged
# 可选依赖(代码校验用,若项目已有可跳过)
npm install --save-dev eslint prettier eslint-config-prettier eslint-plugin-prettier
说明:
@commitlint/config-conventional:内置了 Conventional Commits 规范的校验规则,无需自己编写;eslint-config-prettier和eslint-plugin-prettier:解决 ESLint 和 Prettier 的规则冲突,让两者协同工作。
第二步:配置Commitlint(校验Commit信息)
创建 Commitlint 配置文件,指定校验规则,让它遵循 Conventional Commits 规范:
- 在项目根目录创建
commitlint.config.js文件; - 写入以下配置(固定格式,可直接复制):
// commitlint.config.js
module.exports = {
// 继承官方的Conventional Commits规范
extends: ['@commitlint/config-conventional'],
// 自定义校验规则(可选,根据团队需求调整)
rules: {
// type的枚举值,和Conventional Commits规范一致,可新增自定义type
'type-enum': [
2, // 2表示错误级别(0=禁用,1=警告,2=错误)
'always', // always表示必须满足
[
'feat', // 新增功能
'fix', // 修复bug
'docs', // 文档更新
'style', // 代码风格调整
'refactor', // 代码重构
'test', // 测试相关
'chore', // 构建/依赖/工具相关
'perf', // 自定义:性能优化(可选)
'revert' // 自定义:回滚提交(可选)
]
],
// type不能为空
'type-empty': [2, 'never'],
// description不能为空
'subject-empty': [2, 'never'],
// description首字母小写
'subject-case': [2, 'never', ['start-case', 'pascal-case', 'upper-case']],
// body和description之间要有空行
'body-leading-blank': [1, 'always'],
// footer和body之间要有空行
'footer-leading-blank': [1, 'always']
}
};
配置说明:
extends: ['@commitlint/config-conventional']:核心配置,继承官方规范,无需自己编写复杂规则;rules:自定义校验规则,比如新增perf类型、限制 description 首字母小写等,可根据团队需求调整;- 规则格式:
[错误级别, 是否必须, 具体规则],2(错误)级别会直接拦截提交,1(警告)级别仅提示不拦截。
第三步:配置Husky(关联Git钩子)
Husky 8.x 的配置方式和旧版本(7.x及以下)不同,无需手动创建 .husky 目录,通过命令自动配置,步骤如下:
- 启用 Husky,在项目根目录生成
.husky目录(存储钩子配置):npx husky install - 设置 Husky 自动启用(避免每次克隆项目后手动执行
npx husky install),在package.json中添加prepare脚本:npm set-script prepare "husky install"执行后,package.json中会新增:"prepare": "husky install",后续项目安装依赖(npm install)后,会自动启用 Husky。 - 配置
commit-msg钩子(校验Commit信息):npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'执行后,会在.husky目录下生成commit-msg文件,里面包含校验脚本,当开发者提交Commit信息时,会自动执行Commitlint校验。 - (可选)配置
pre-commit钩子(关联lint-staged,校验代码):npx husky add .husky/pre-commit 'npx lint-staged'执行后,.husky目录下会生成pre-commit文件,提交代码前会自动执行 lint-staged 校验。
注意:如果执行 npx husky add 命令报错,可手动创建 .husky 目录,再手动创建对应钩子文件(下文异常排查会讲)。
第四步:配置lint-staged(校验本次提交的代码)
lint-staged 的配置很灵活,可在 package.json 中添加配置,也可创建单独的 .lintstagedrc.js 文件,这里推荐在 package.json 中配置,更简洁:
{
"name": "your-project",
"version": "1.0.0",
// 新增lint-staged配置
"lint-staged": {
// 匹配所有.js、.jsx、.ts、.tsx文件(根据项目类型调整)
"*.{js,jsx,ts,tsx}": [
"eslint --fix", // 自动修复ESLint错误
"prettier --write" // 自动格式化代码(若用Prettier)
],
// 匹配所有.css、.scss文件(样式文件格式化)
"*.{css,scss}": [
"prettier --write"
],
// 匹配所有.md文件(文档格式化)
"*.md": [
"prettier --write"
]
}
}
配置说明:
- 键(如
*.{js,jsx,ts,tsx}):匹配暂存区的文件类型,可根据项目实际情况调整(如Vue项目可添加*.vue); - 值(数组):对匹配到的文件执行的命令,顺序执行,先修复ESLint错误,再格式化代码;
- 如果项目不需要 Prettier,可删除
prettier --write命令,只保留eslint --fix; - 如果只需要校验Commit信息,不需要代码校验,可跳过此步骤,删除
pre-commit钩子即可。
第五步:(可选)配置ESLint和Prettier(代码校验基础)
如果项目还未配置 ESLint 和 Prettier,可参考以下简单配置(确保 lint-staged 能正常工作):
- 创建 ESLint 配置文件
.eslintrc.js:
// .eslintrc.js
module.exports = {
env: {
browser: true,
es2021: true,
node: true
},
extends: [
'eslint:recommended',
'plugin:prettier/recommended' // 整合Prettier规则
],
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module'
},
rules: {
// 自定义ESLint规则,根据团队需求调整
'no-console': 'warn',
'no-unused-vars': 'warn'
}
};
- 创建 Prettier 配置文件
.prettierrc.js:
// .prettierrc.js
module.exports = {
printWidth: 100, // 每行最大长度
tabWidth: 4, // 缩进宽度
useTabs: false, // 不使用制表符,用空格
singleQuote: true, // 单引号
trailingComma: 'es5', // 尾逗号规则
semi: true, // 句尾加分号
bracketSpacing: true // 对象括号前后加空格
};
- 创建
.eslintignore和.prettierignore文件,忽略不需要校验的文件:
.eslintignore 和 .prettierignore 内容一致
node_modules/
dist/
build/
*.config.js // 可选,忽略配置文件
.gitignore
四、实战测试:验证配置是否生效
配置完成后,一定要进行实战测试,确保三个工具能正常协同工作,以下是3个关键测试场景:
测试1:提交不规范的Commit信息(验证Commitlint + Husky)
# 1. 随便修改一个文件,添加到暂存区
git add .
# 2. 提交不规范的Commit信息(type错误+描述模糊)
git commit -m "改bug"
预期结果:提交失败,终端提示错误,提示 type 不合法、description 不符合要求(如“type must be one of [feat, fix, docs, …]”)。
正确提交示例(符合规范): git commit -m "fix(登录): 修复手机号验证码过期的bug"
预期结果:提交成功,无报错。
测试2:提交不符合ESLint规则的代码(验证lint-staged + Husky)
# 1. 写一段不符合ESLint规则的代码(如console.log未删除、变量未使用)
// index.js
const a = 1;
console.log(a);
# 2. 添加到暂存区,提交
git add index.js
git commit -m "feat: 新增测试代码"
预期结果:提交前,lint-staged 自动执行 ESLint 校验,提示错误(如“no-console: Unexpected console statement”),拦截提交,需修复错误后重新提交。
修复方法:删除 console.log,或注释掉,再重新提交。
测试3:自动修复代码格式(验证lint-staged + Prettier)
# 1. 写一段格式不规范的代码(如缩进为2个空格、用双引号)
// index.js
const name = "test";
console.log(name);
# 2. 添加到暂存区,提交
git add index.js
git commit -m "docs: 更新测试代码"
预期结果:提交前,lint-staged 自动执行 Prettier 格式化,将双引号改为单引号、缩进改为4个空格,无需手动修改,直接提交成功。
五、常见异常排查:配置失败?看这里
配置过程中,可能会遇到各种异常,以下是最常见的4种问题及解决方案,帮你快速避坑:
异常1:执行 npx husky add 报错,提示“husky: command not found”
原因:Husky 未正确安装,或未启用。
解决方案: # 重新安装Husky
npm install --save-dev husky
# 重新执行启用命令
npx husky install 若仍报错,手动创建 .husky 目录,再手动创建钩子文件(如 .husky/commit-msg),写入脚本:#!/usr/bin/env sh\nnpx --no -- commitlint --edit $1。
异常2:Commit信息符合规范,但仍提示“type-enum”错误
原因:Commitlint 配置文件中 type-enum 规则的枚举值,和你提交的 type 不匹配(如你提交了 perf,但配置中没有添加)。
解决方案:修改 commitlint.config.js 中的 type-enum 数组,添加你使用的 type(如 'perf')。
异常3:lint-staged 不执行,提交代码时无任何校验
原因1:pre-commit 钩子未正确配置,或脚本错误;
解决方案1:重新执行 npx husky add .husky/pre-commit 'npx lint-staged',确保 pre-commit 文件中的脚本正确。
原因2:暂存区没有文件,或文件类型不匹配 lint-staged配置中的匹配规则;
解决方案2:确保有文件被 git add 到暂存区,且文件类型符合配置(如 .js 文件)。
异常4:ESLint 和 Prettier 冲突,提示“prettier/prettier”错误
原因:ESLint 和 Prettier 的规则冲突(如 ESLint 允许双引号,Prettier 要求单引号)。
解决方案:确保已安装eslint-config-prettier 和 eslint-plugin-prettier,且 .eslintrc.js中 extends 包含 'plugin:prettier/recommended',让 Prettier 规则覆盖 ESLint 冲突规则。
六、进阶优化:让配置更贴合团队需求
基础配置完成后,可根据团队实际需求,进行以下进阶优化,提升实用性:
1. 自定义Commitlint规则,适配团队规范
比如团队要求 description 长度不超过 50 字符,可在 commitlint.config.js 中添加:
rules: {
// description长度不超过50字符
'subject-max-length': [2, 'always', 50]
}
2. 新增自定义type,适配项目场景
比如电商项目需要 feat(支付),可在type-enum 中添加 'pay':
'type-enum': [
2,
'always',
[
'feat', 'fix', 'docs', 'style', 'refactor', 'test', 'chore',
'pay' // 自定义type:支付相关功能
]
]
3. 集成 Commitizen,实现交互式提交
结合上一篇提到的 Commitizen,让开发者通过交互式命令填写Commit信息,避免手动书写出错,配置步骤:
# 1. 安装依赖
npm install --save-dev commitizen cz-conventional-changelog
# 2. package.json 中添加配置
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
},
"scripts": {
"commit": "cz"
}
# 3. 提交时执行 npm run commit,代替 git commit
npm run commit
执行后,会出现交互式提示,引导你选择 type、输入 scope 和 description,自动生成符合规范的Commit信息。
4. 忽略特定文件的校验
如果某些文件不需要校验(如第三方插件、配置文件),可在 lint-staged 配置中添加 ignore 选项:
"lint-staged": {
"*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
],
"ignore": ["**/node_modules/**", "**/config/**"]
}
七、总结
Commitlint + Husky + lint-staged 这套工具链,核心价值是“将规范自动化”——它不用再靠人工监督,而是通过Git钩子,在提交代码的关键节点自动校验,拦截不规范的Commit信息和代码,让 Conventional Commits 规范真正落地,同时保证代码质量。
本文的配置步骤覆盖了从依赖安装到实战测试的全流程,无论是个人项目还是团队协作,都能直接照搬使用;如果团队有特殊需求,可在基础配置上调整规则、新增自定义type,适配项目场景。
配置完成后,团队的Commit信息会变得统一规范,代码格式也会保持一致,后续的代码审查、版本追溯、CHANGELOG自动生成都会变得更高效,真正实现“工程化规范落地”。
最后,附上一份配置速查表,方便你日常查阅和维护:
# 核心命令
npm install --save-dev @commitlint/cli @commitlint/config-conventional husky lint-staged
npx husky install
npm set-script prepare "husky install"
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'
npx husky add .husky/pre-commit 'npx lint-staged'
# 常用测试命令
git commit -m "fix: 测试不规范提交" # 测试Commitlint
npm run commit # 交互式提交(若配置Commitizen)
# 常见异常排查
1. Husky报错:重新安装Husky,手动创建钩子文件
2. Commitlint报错:检查type是否在配置的枚举中
3. lint-staged不执行:检查pre-commit钩子和文件匹配规则
希望本文能帮你快速落地这套工程化配置,让你的项目规范更完善、协作更高效!
附:配置完成后的完整项目目录结构(对照参考)
为了进一步保证配置的严谨性,方便你对照自身项目,确认所有配置文件是否齐全、路径是否正确,以下是配置完成后(含ESLint、Prettier、Commitizen)的标准项目目录结构,重点标注了本文配置的核心文件,可直接对照检查:
your-project/ # 项目根目录
├─ .husky/ # Husky钩子配置目录(自动生成)
│ ├─ commit-msg # Commit信息校验钩子(核心文件)
│ └─ pre-commit # 代码校验钩子(核心文件)
├─ .eslintrc.js # ESLint配置文件(可选,代码校验用)
├─ .eslintignore # ESLint忽略文件(可选)
├─ .prettierrc.js # Prettier配置文件(可选,代码格式化用)
├─ .prettierignore # Prettier忽略文件(可选)
├─ commitlint.config.js # Commitlint配置文件(核心文件)
├─ package.json # 项目依赖+lint-staged/Commitizen配置(核心文件)
├─ package-lock.json # 依赖版本锁文件(自动生成)
├─ index.js # 项目入口文件(示例)
└─ README.md # 项目说明文档
补充说明(贴合前文配置,避免误解):
- 若不需要代码校验(仅需Commit信息校验),可删除
.eslintrc.js、.eslintignore、.prettierrc.js、.prettierignore四个文件,同时删除.husky/pre-commit钩子,不影响Commit信息校验功能; - 若未配置Commitizen,仅需删除
package.json中对应的config配置和"commit": "cz"脚本,不影响核心的校验功能; - 本文所有配置文件均需放在项目根目录下,无需嵌套到其他文件夹,避免路径错误导致配置失效,这也是前文配置步骤中反复强调的重点。
更多推荐
所有评论(0)