提交信息这东西,平时没人看,可真要回溯问题时,一条条"update"能让你对着 git log 骂十分钟。去年帮团队收拾一个历史项目,我第一件事就是装 commitlint,从安装到配置到让所有人养成习惯,前后折腾了几天。这篇就完整记录一下我是怎么做的,踩过哪些坑,以及最后沉淀下来的推荐配置。不管你是刚接触 commitlint 的新手,还是已经在用但偶尔被诡异问题卡住的开发者,照着这份流程走,基本都能顺利落地。
1. 提交信息失控之前,没人觉得这是问题
1.1 没有规则的 git log 到底有多可怕
先看一个我真实遇到过的提交历史片段:
text复制* 2024-06-03 fix
* 2024-06-01 update
* 2024-05-29 代码提交
* 2024-05-28 修改
* 2024-05-26 add something
如果这是你自己刚写完还没合并的分支,可能还能凭记忆想起每次改了什么。但如果是三个月前的线上故障排查,你需要在海量提交里找出"到底是哪一次改动导致订单金额算错",这种提交信息基本等于没有。我当时面对的就是这么一摊历史,代码 review 的时候 reviewer 只能逐个打开 diff 猜改动意图,效率极低。
后来我把规范后的提交信息拉出来,画风是这样的:
text复制* 2024-07-12 fix(order): 修复满减活动金额精度丢失问题
* 2024-07-11 feat(user): 新增手机号一键登录
* 2024-07-10 docs(readme): 补充本地开发环境搭建步骤
区别是肉眼可见的。type 指明这次提交的性质,scope 指出影响模块,subject 用一句话说明做了什么。别人 review、回溯、写 changelog 时,不需要点开代码就能知道每次提交的目的。
1.2 commitlint 在整条链路里到底管什么
commitlint 是一个专门校验 Git 提交信息的工具,它不检查你的代码质量,不检查有没有语法错误,只检查你写的 commit message 是否符合约定格式。它的设计思路和 ESLint 很像:你定义规则,它负责在提交时拦一道,不满足规则就不允许提交通过。
这里要厘清一个边界。很多人以为装完 commitlint 就能自动规范提交,其实 commitlint 本身只是一个"校验器",它需要三个环节配合才完整:
- commitlint CLI:负责实际执行校验,读取你写好的提交信息然后逐条对照规则;
- 配置文件:告诉它用哪套规则,比如继承官方推荐的 conventional 配置,还是自定义类型范围;
- Git 钩子:解决"什么时候触发校验"的问题,通常是 husky 把 commit-msg 钩子挂上,让每一次 git commit 都自动跑一次校验。
这也回答了经常被问的问题:commitlint 能不能拦 git commit --no-verify?技术上拦不住,--no-verify 本来就是 Git 给用户的逃生门,commitlint 更像是一个"提醒机制",真正想让所有人规范,还得靠习惯、交互工具和 CI 双保险。后面我会详细说怎么搭这套组合拳。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 安装之前先把 commitlint、husky、config 这三兄弟弄明白
2.1 三个包各自扮演什么角色
很多教程直接让执行 npm install -D @commitlint/cli @commitlint/config-conventional,但没解释为什么需要两个包里还有一个 husky。结果很多人装完一头雾水,配置也写不对。
我觉得最直观的理解方式是:commitlint 是一条专门的"交警",但它不会自己跑到马路上执勤,需要有人把它安排在路口;husky 就是那个安排它上岗的人。
用到的包通常有这么几个:
| 包 | 作用 | 必要性 |
|---|---|---|
| @commitlint/cli | 核心命令行工具,负责解析提交信息、执行校验规则 | 必装 |
| @commitlint/config-conventional | 官方预置规则集,基于 Conventional Commits 约定 | 建议装 |
| husky | Git hooks 管理工具,在 commit 时触发 commitlint | 必装 |
其中 @commitlint/config-conventional 里的规则不是随便定的,它对应的是社区广泛使用的 Conventional Commits 规范,格式长这样:
text复制type(scope): subject
type 是提交类型,比如 feat 表示新功能、fix 表示修复缺陷;scope 是影响范围,可选项,比如 login、order;subject 是简短描述。如果想支持破坏性变更,还可以在冒号前加感叹号,比如 feat!(api): 调整接口返回结构。
2.2 版本和 Node 环境要求
commitlint 当前稳定大版本已经到 19.x,husky 主流是 v9,两个工具对 Node 版本都有要求。如果 Node 还是老旧的 14、16,装最新版大概率会在安装阶段或运行阶段报错。我在本机统一用 Node 18 LTS 以上版本,实测下来比较省心。
版本兼容是最容易被忽略的坑。husky v4 和 v9 的配置方式完全是两代东西,v4 时代很多人习惯在 package.json 里维护 husky 配置项:
json复制{
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
}
}
这套写法在 husky v9 已经不再生效。如果从网上复制了旧教程,会发现钩子怎么都不触发。我在 5.1 节会展开讲怎么排查这类历史遗留问题。
安装命令建议一次性装齐:
bash复制npm install --save-dev @commitlint/cli @commitlint/config-conventional husky
这里特意用 --save-dev,是因为这些工
