【Other】使用 husky + commitlint 來規範 commit message
在 開發專案時,commit message 是很重要的一環,因為它可以讓我們知道這次 commit 做了什麼事情,很常在多人協作的時候會發生 commit message 不統一,導致後續要找特定的 commit 會很難找。所以本篇介紹使用 husky + commitlint + lint-staged 來規範 commit message。
套件介紹
- husky : 可以在 git hook 執行 script 的套件
- commitlint : 可以讓我們規範 commit message 的套件
安裝流程
Husky
npx husky-init && npm install
上面指令會建立一個 .husky 的資料夾,裡面會有 husky.sh
執行檔跟預設的 pre-commit
的檔案,會在 commit 前會去執行裡面的指令,像是 prettier、eslint 等等會在 commit 之前執行,而 husky 預設是執行 npm test。
並且會在 package.json 中加入 husky install 的 script。
{
"scripts": {
"prepare": "husky install"
}
}
這個 script 會在 npm install 的時候執行,用意是當其他人下載專案包時可以自動執行 husky install,載入 .husky.sh
的執行檔。
husky 的 hook 檔案像是 pre-commit
或 commit-msg
要記得加入 git 版控,才可以執行 hook 指令。
Commitlint
npm i @commitlint/cli @commitlint/config-conventional -D
*@commitlint/config-conventional 會提供基本的規範,如果想要客製化的可以不用安裝。
安裝完後要建立 commitlint.config.js
配置檔,可以在裡面設定 commit message 的規則
module.exports = {
rules: {
"header-min-length": [2, "always", 5],
},
};
rules 項目的 value 會是一個陣列傳入三個設定
- level(要不要開啟這個規則):0 = disable, 1 = warning, 2 = error
- applicable(設定規則是否遵守):always | never
- value:規則的值
上面的例子就是開啟設定 header 的最小長度為 5
個字元。更多的條件可以參考 commitlint rules。
接著就可以測試看看是否有套用規則
echo "test" | npx commitlint
因為字數沒有符合規則,就會顯示不通過及違反的規則
如果在 package.json 有設定 "type": "module"
,記得要把 commitlint.config.js
檔改成 commitlint.config.cjs
,在執行 script 時要執行 echo "test" | npx commitlint --config
不然會有 ESModule 的報錯。
config-coventional
前面提到的 @commitlint/config-conventional 如果有安裝,可以把它加入到 commitlint.config.js
的 extends。
module.exports = {
extends: ["@commitlint/config-conventional"],
rules: {
"header-min-length": [2, "always", 5],
},
};
他有幫你設定基本的預設規則,像是 type 只能使用有意義的詞,例如:feat、chore、fix 等等。
設定完 commitlint 後要把它加入到 husky 的 hook
npx husky add .husky/commit-msg 'npx --no-install commitlint --edit "$1"'
這樣會在 .husky 底下建立 commit-msg 的 hook 檔案,在 commit 時把 commit message 傳入,並且去跑 commitlint 的檢查。
這樣就完成了 husky + commitlint 的設定,可以在 commit 時進行規範!
Commitizen
除了一般的輸入 commit message ,還可以使用 commitizen 建立問答的方式來進行 commit。首先要安裝 commitizen
npm i commitizen -D
commitlint 有提供 cz-commitlint 可以結合 commitizen 跟 commitlint 本身的 prompt 進行問答
npm i @commitlint/cz-commitlint -D
然後在 package.json 的 script 加上
{
"scripts": {
"commit": "git-cz"
}
}
以及 config 的設定
{
"config": {
"commitizen": {
"path": "@commitlint/cz-commitlint"
}
}
}
如果使用 @commitlint/config-conventional 擴充的話,他也有預設好的 prompt 可以使用
只要下指令
npm run commit
就可以進行問答式的 commit message
客製化 commit message
cz-customizable
如果不想使用 @commitlint/config-conventional 提供的 prompt,除了可以在 commitlint 客製化 prompt,這邊推薦另一個套件 cz-customizable 可以更方便的客製化問答式
npm i cz-customizable -D
並把原本的 config path 改成 cz-customizable
{
"config": {
"commitizen": {
"path": "cz-customizable"
}
}
}
接著在根目錄建立 .cz-config.js
檔案,裡面可以設定問答的內容
module.exports = {
// 配置 type 的選項,限制只能提交以下類型
types: [
{
value: "feat",
name: "feat: 新增功能",
},
{
value: ":bug: fix",
name: "fix: 解決 bug 或 issue",
},
],
// 每一步的提示信息
messages: {
type: "請選擇提示訊息",
scope: "請選擇 scope(選填)",
subject: "請輸入 commit 內容(必填)",
body: "請輸入 commit description,可透過 & 換行(選填)",
breaking: "列出任何 BREAKING CHANGES(重大修改)(選填)",
footer: "請輸入相關的的 issue(跟 issue 有關的 commit)(選填)",
confirmCommit: "確定提交此 commit 嗎?",
},
// 跳過要求的步驟
skipQuestions: ["scope", "breaking", "footer"],
};
詳細內容可以參考設定範例。
一樣如果在 package.json 有設定 "type": "module"
,記得要把 .cz-config.js
檔改成 .cz-config.cjs
,不然會有 ESModule 的報錯,然後要在 package.json 的 config 加上 config 的路徑。
{
"config": {
"commitizen": {
"path": "cz-customizable"
},
"cz-customizable": {
"config": ".cz-config.cjs"
}
}
}
最後執行原本的 npm run commit
,就可以看到客製化的問答式 commit。