感謝bigAken投稿
在每一個使用 git 進行版本管理的倉庫,都有一個目錄 .git/hooks,包含 commit 各個階段 Hooks 的腳本。這些 Hooks 在 git 操作 commit、push、merge 等得時候,可以做前置或者後置的操作,例如 pre-commit 在 git commit 前可以做代碼校驗,校驗代碼的時候使用的ESLint,格式化使用的是 prettier。Git 支持的常用鉤子見下表,更多請查看官網Hooks:
Git Hook調用時機調用時機pre-commitgit commit 執行前可以用 git commit --no-verify 繞過commit-msggit commit 執行前可以用 git commit --no-verify 繞過pre-merge-commitgit merge 執行前可以用 git merge --no-verify 繞過pre-pushgit push 執行前本文先實踐,怎麼去寫 pre-commit 這個 git hooks,然後介紹 husky,lint-staged,commitlint 的使用
在 git 項目中,.git/hooks下面有很多 hooks 示例如下
這些 git hooks 都是.sample結尾的,如果要啟用某個 hooks 用可以去掉.sample結尾
實踐npm init -y初始化一個項目,然後git init,然後npm install eslint --save-dev
新建.gitignore文件
node_modules
# local env files
.env.local
.env.*.local
# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
*-lock.json
*.lock新建.eslintrc,配置 eslint
{
"rules": {
// 要求使用分號
"semi": ["error", "always"],
// 強制使用一致的反勾號、雙引號或單引號
"quotes": ["error", "double"]
}
}新建src目錄,然后里面新建index.js,禁止使用快捷鍵格式化
console.log('object')根目錄新建文件夾.customGitHooks然後 git config 'core.hooksPath' .customGitHooks,主要是設置 gitHooks 的存放目錄,因為 gitHooks 默認存放目錄是.git/hooks,新建pre-commit,寫入如下
#!/bin/sh
echo 'start check your code,please wait...'
# git diff 獲取更改的內容 可以通過參數--diff-filter 配置條件
npx eslint $(git diff --cached --name-only --diff-filter=ACM -- '*.js')
# 變量$?--->上一個命令的執行狀態結果
if [ $? != '0' ];then
echo "ending and failed,please check your code;"
exit 1
else
echo "check pass"
fi這時候,執行git add .,git commit -m 'test'就會發現沒有 commit 成功,報錯了,如下圖
如果把 index.js 的代碼修改如下:
console.log('object')執行git add . ,git commit -m 'test'就會發現 eslint 代碼檢查通過了,能正常提交了,以上實踐能很好解釋 commit 前怎麼檢驗代碼,但是有個缺點就是別人 pull 你的代碼要執行git config 'core.hooksPath' .customGitHooks能起作用;下面就介紹 husky,lint-staged,commitlint 的使用
.git 文件夾不會被跟蹤並且上傳至遠程倉庫的
Huskygithub為了解決.git配置不能提交遠程倉庫的問題,husky 出來了,husky 在你npm i安裝完依賴只有自動執行husky install
安裝 npm install husky -Dnpm install husky -D
使用編輯package.json在script裡添加prepare的值為husky install
"scripts": {
"prepare":"husky install"
},然後執行npm run prepare,做了什麼事呢
源碼index.ts中,我們看到執行 husky install 實際上就是創建 .husky 目錄,複製../husky.sh文件到該目錄下,配置了一個.gitignore,設置了core.hooksPath(設置 .husky 目錄為 git hooks 目錄)
添加一個 hook在.husky目錄下創建pre-commit
#!/bin/sh
echo 'start check your code,please wait...'
# git diff 獲取更改的內容 可以通過參數--diff-filter 配置條件
npx eslint $(git diff --cached --name-only --diff-filter=ACM -- '*.js')
# 變量$?--->上一個命令的執行狀態結果
if [ $? != '0' ];then
echo "ending and failed,please check your code;"
exit 1
else
echo "check pass"
fiindex.js文件內容如下
console.log('object')然後執行git add .,git commit -m 'test'發現代碼已經被攔截,沒有提交,因為index.js代碼不符合規範
遺留問題就是 git hooks 不會編寫怎麼辦,下面 lint-staged 出來了
lint-staged配置例子作用:對 Git 暫存區代碼文件進行 bash 命令操作等等
npm i lint-staged -D根目錄下新建.lintstagedrc文件
{
"*.js": "eslint"
}把husky目錄下的pre-commit修改如下
. "$(dirname "$0")/_/husky.sh"
npm run lintpackage.json添加script
"scripts": {
"lint": "lint-staged"
}index.js如下
console.log('object')
console.log('object')執行git add .,git commit -m 'test',可以發現調用了 eslint 去檢查代碼,檢查不通過就退出commit
綜上,代碼檢測規範有了,現在也需要規範一下提交規範;
commitlintgithub
校驗 commit 提交的信息
npm install --save-dev @commitlint/config-conventional @commitlint/cli
使用新建commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
rules: {
'type-enum': [2, 'always', ['build', 'ci', 'docs', 'feat', 'fix', 'perf', 'refactor', 'style', 'test', 'revert', 'chore']],
'type-case': [0],
'type-empty': [0],
'scope-empty': [0],
'scope-case': [0],
'subject-full-stop': [0, 'never'],
'subject-case': [0, 'never'],
'header-max-length': [0, 'always', 72]
}
}配置git hooks,執行下面命令
npx husky add .husky/commit-msg 'npx --no -- commitlint --edit $1'commit message 一般分為三個部分 Header,Body 和 Footer
header
<type>(<scope>): <subject>
// 空一行
<body>
// 空一行
<footer>
其中,Header 是必需的,Body 和 Footer 可以省略接下來提交的 commit 必須符合下面的格式
注意冒號後面有空格
git commit -m <type>[optional scope]: <description>常用的 type 類別
build:主要目的是修改項目構建系統(例如 glup,webpack,rollup 的配置等)的提交ci:主要目的是修改項目繼續集成流程(例如 Travis,Jenkins,GitLab CI,Circle 等)的提交refactor:重構代碼(既沒有新增功能,也沒有修復 bug)style:不影響程序邏輯的代碼修改(修改空白字符,補全缺失的分號等)optional scope:一個可選的修改範圍。用於標識此次提交主要涉及到代碼中哪個模塊。
description:一句話描述此次提交的主要內容,做到言簡意賅。
這時候,執行一次測試一下
git add .
git commit -m 'test'因為該提交的 commit 是不規範的所以提交時失敗的 如下圖
如果把 commit 修改,就會提交成功,因為符合 commit 規範
git add .
git commit -m 'feat: test'但是問題又來了,每次 commit 都要輸入,有點不方便;而且有可能輸錯下面就介紹到 commitizen
commitizencz-commitlint
生成符合規範的 commit message
本地安裝並沒有全局安裝,當然可以全局安裝具體查看官方文檔,全局安裝可以使用git cz,cz-commitlint打通 commitizen 和commitlint配置
npm install --save-dev @commitlint/cz-commitlint commitizen然後
npx commitizen init cz-conventional-changelog --save-dev --save-exactpackage.json添加script
{
"scripts": {
"commit": "git-cz"
},
"config": {
"commitizen": {
"path": "@commitlint/cz-commitlint"
}
}
}新建commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional']
}然後執行
git add .npm run commit發現為中文提示如下圖
再次修改commitlint.config.js
module.exports = {
extends: ['@commitlint/config-conventional'],
prompt: {
questions: {
type: {
description: '選擇你要提交的類型:',
enum: {
feat: {
description: '新功能',
title: 'Features',
emoji: '✨'
},
fix: {
description: '修復相關bug',
title: 'Bug Fixes',
emoji: '🐛'
},
docs: {
description: '文檔更改',
title: 'Documentation',
emoji: '📚'
}
}
}
}
}
}然後執行
git add .npm run commit可以看到變成中文了,具體參考官網
接下來提交信息 執行npm run commit,就可以按照規範提交了;如果沒有使用commitlint,在 commitizen中使用 cz-customizable也可以自定義很多配置的