cover

給每次寫 commit message 都在即興創作的你。這是系列文的第一篇,講 CommitLint 本體;工具生態系和團隊導入策略請看 下篇

先講結論

CommitLint 就是 commit message 的 ESLint——你寫的提交訊息不合格式,直接擋掉不讓你 commit。搭配 Husky 設定 Git hook,整個過程全自動,不用靠人工 code review 來抓格式問題。

裝完之後你的 commit 會長這樣:feat(login): add user authentication,而不是 updatefix修了一些東西

為什麼你該在意 commit message?

你有沒有打開過 git log,看到滿滿的 fix bugupdatewip?三個月後回來看,根本不知道當時改了什麼、為什麼改。

好的 commit message 不只是整齊好看。它能讓你:

  • 快速定位問題git log --oneline 一眼就知道哪個 commit 改了什麼
  • 自動產生 CHANGELOG:工具能解析 featfix 自動分類
  • Code review 更有效率:reviewer 看訊息就知道這個 PR 在幹嘛

Conventional Commits 格式

CommitLint 預設用的就是這套規範:

type(scope): description
  • typefeat(新功能)、fix(修 bug)、docs(文件)、refactor(重構)、chore(雜事)…
  • scope:可選,說明改到哪個模組,像 loginapicart
  • description:簡短描述,用祈使句(add 不是 added)

五分鐘裝好 CommitLint + Husky

確認你有 Node.js 和 npm,然後跑:

# 安裝 CommitLint
npm install --save-dev @commitlint/{config-conventional,cli}
 
# 安裝 Husky 並初始化
npm install --save-dev husky
npx husky init
 
# 設定 commit-msg hook
echo 'npx --no -- commitlint --edit "$1"' > .husky/commit-msg

再建一個 commitlint.config.js

module.exports = { extends: ['@commitlint/config-conventional'] };

搞定。從現在開始,每次 git commit 都會自動檢查訊息格式。

實際體驗:被擋住是什麼感覺?

會過的:

git commit -m "feat(login): add user authentication"
git commit -m "fix(api): handle null response from payment gateway"
git commit -m "docs: update README with setup instructions"

會被擋的:

git commit -m "Added user authentication feature"
# ✖ subject may not be empty
# ✖ type may not be empty
 
git commit -m "fix bug"
# ✖ subject may not be empty("fix" 被當 type,後面沒 description)

第一次被擋會有點煩,但你很快就會習慣——就像第一次被 ESLint 擋 console.log 一樣,煩到後來就不寫了

CommitLint 的好處和代價

好處很明顯:

  • 團隊的 commit history 終於能看了
  • 可以自動產生 CHANGELOG(搭配工具,下篇會講)
  • 新人看 git log 就能理解專案脈絡

代價也要誠實講:

  • 團隊需要學新格式,初期會被擋到暴躁
  • Husky + CommitLint 的初始設定需要花點時間
  • 某些 edge case 下格式太嚴格會卡住(但可以自訂規則放寬)

我的看法是:代價是一次性的,好處是累積的。撐過第一週就回不去了。


好的 commit message 就像好的變數命名——寫的時候多花三秒,讀的時候省三十分鐘。

下篇:CommitLint 工具生態系:lint-staged、commitizen 與團隊導入策略

參考資源