今天合代码准备发布新版本,点开 Git 提交历史,血压瞬间拉满。一排排提交记录里写着“fix”、“update”、“测试一下”、“111”甚至干脆就是“debug”。这些毫无信息量的 Commit Message 让人根本看不出这次发版到底修了什么 Bug,上了什么功能。

一旦项目规模变大,不规范的 Git 提交记录会让追溯历史问题变得极其痛苦。如果每次发布 CHANGELOG 还要靠人工去翻 PR 一个个肉眼整理,这纯粹是在浪费生命。

规范化提交记录的最佳时机是在本地 commit 时直接拦截。为了解决这个问题,我们团队在前端和 Node 后端项目中,引入了 huskycommitlint 构建的 Git Hook 约束体系。

以下是完整的工具链集成配置与初始化步骤,直接拷过去就能在你的项目里跑起来:

第一步,在项目根目录下安装依赖:

npm install --save-dev @commitlint/config-conventional @commitlint/cli husky lint-staged

第二步,在根目录下编写 commitlint.config.js 规则文件:

module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    // 强制 scope 必须小写
    'scope-case': [2, 'always', 'lower-case'],
    // 强制 subject 不能为空
    'subject-empty': [2, 'never'],
    // 限制首字母不能大写
    'subject-full-stop': [2, 'never', '.'],
    // 限制 header 的总长度不超过 72 个字符
    'header-max-length': [2, 'always', 72],
    // 约束 type 的取值范围,必须是以下约定类型之一
    'type-enum': [
      2,
      'always',
      [
        'build',    // 构建系统、依赖变更(例如 glup, webpack, npm 等)
        'chore',    // 构建过程或辅助工具的变动(不影响源码及测试)
        'ci',       // CI 配置文件及脚本的变更
        'docs',     // 文档修改(Markdown 等)
        'feat',     // 新功能(feature)
        'fix',      // 修补 Bug
        'perf',     // 性能优化
        'refactor', // 代码重构(不包括 Bug 修复或功能新增)
        'revert',   // 回滚到历史 Commit
        'style',    // 代码格式变更(不影响代码逻辑的空格、分号等格式)
        'test'      // 增加测试或修改已有测试
      ]
    ]
  }
};

第三步,在项目的 package.json 中配置 husky 自动初始化以及 lint-staged 钩子:

{
  "name": "homework-money-printer",
  "version": "1.0.0",
  "scripts": {
    "prepare": "husky install"
  },
  "lint-staged": {
    "src/**/*.{js,ts,tsx}": [
      "eslint --fix",
      "prettier --write"
    ]
  }
}

第四步,在本地执行以下命令激活 Git Hooks,并添加 commit-msg 钩子拦截脚本:

# 激活 husky
npm run prepare

# 添加 commit-msg 校验钩子
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'

# 添加 pre-commit 代码质量与格式化校验钩子
npx husky add .husky/pre-commit 'npx lint-staged'

这套管线配置搞定后,开发者再想像以前那样随手写一句 git commit -m "update" 就会直接报错拒绝提交。团队成员必须规规矩矩地按照 feat(auth): add google oauth loginfix(api): solve db memory leak 的标准格式来提交代码。

虽然前期在推行时大家觉得有些被规则绑架,心智负担有点高,但两周下来,项目的 Git 树清晰得像教科书一样,用语义化发布工具也可以一键生成漂亮又规范的 Release Changelog。

你们团队在落地 Conventional Commits 时有没有遇到开发同学的强烈吐槽?大家一般是用交互式的 commitizen 来引导编写,还是跟我们一样采用强硬的 commitlint 在提交前硬性拦截?