大家好,我是若川。最近組織了源碼共讀活動,感興趣的可以加我微信?ruochuan12?參與,每周大家一起學習200行左右的源碼,共同進步。已進行四個月了,很多小伙伴表示收獲頗豐。
想學源碼,極力推薦訂閱我寫的《學習源碼整體架構系列》?包含20余篇源碼文章。同時推薦參與源碼共讀活動。
感謝bigAken投稿
在每一個使用 git 進行版本管理的倉庫,都有一個目錄 .git/hooks,包含 commit 各個階段 Hooks 的腳本。這些 Hooks 在 git 操作 commit、push、merge 等得時候,可以做前置或者后置的操作,例如 pre-commit 在 git commit 前可以做代碼校驗,校驗代碼的時候使用的ESLint,格式化使用的是 prettier。Git 支持的常用鉤子見下表,更多請查看官網Hooks:
Git Hook | 調用時機 | 調用時機 |
---|---|---|
pre-commit | git commit 執行前 | 可以用 git commit --no-verify 繞過 |
commit-msg | git commit 執行前 | 可以用 git commit --no-verify 繞過 |
pre-merge-commit | git merge 執行前 | 可以用 git merge --no-verify 繞過 |
pre-push | git 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/shecho?'start?check?your?code,please?wait...'
#?git?diff?獲取更改的內容?可以通過參數--diff-filter?配置條件
npx?eslint?$(git?diff?--cached?--name-only?--diff-filter=ACM?--?'*.js')
#?變量$?--->上一個命令的執行狀態結果
if?[?$??!=?'0'?];thenecho?"ending and failed,please check your code;"exit?1
elseecho?"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 文件夾不會被跟蹤并且上傳至遠程倉庫的
Husky
github為了解決.git
配置不能提交遠程倉庫的問題,husky
出來了,husky 在你npm i
安裝完依賴只有自動執行husky install
安裝 npm install husky -D
npm?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/shecho?'start?check?your?code,please?wait...'
#?git?diff?獲取更改的內容?可以通過參數--diff-filter?配置條件
npx?eslint?$(git?diff?--cached?--name-only?--diff-filter=ACM?--?'*.js')
#?變量$?--->上一個命令的執行狀態結果
if?[?$??!=?'0'?];thenecho?"ending and failed,please check your code;"exit?1
elseecho?"check?pass"
fi
index.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?lint
package.json
添加script
"scripts":?{"lint":?"lint-staged"
}
index.js
如下
console.log('object')
console.log('object')
執行git add .
,git commit -m 'test'
,可以發現調用了 eslint 去檢查代碼,檢查不通過就退出commit

綜上,代碼檢測規范有了,現在也需要規范一下提交規范;
commitlint
github
校驗 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 等)的提交
docs:文檔更新
feat:新增功能
fix:bug 修復
perf:性能優化
refactor:重構代碼(既沒有新增功能,也沒有修復 bug)
style:不影響程序邏輯的代碼修改(修改空白字符,補全缺失的分號等)
test:新增測試用例或是更新現有測試
revert:回滾某個更早之前的提交
chore:不屬于以上類型的其他類型(日常事務)
optional scope:一個可選的修改范圍。用于標識此次提交主要涉及到代碼中哪個模塊。
description:一句話描述此次提交的主要內容,做到言簡意賅。
這時候,執行一次測試一下
git?add?.
git?commit?-m?'test'
因為該提交的 commit 是不規范的所以提交時失敗的 如下圖

如果把 commit 修改,就會提交成功,因為符合 commit 規范
git?add?.
git?commit?-m?'feat:?test'

但是問題又來了,每次 commit 都要輸入,有點不方便;而且有可能輸錯 下面就介紹到 commitizen
commitizen
cz-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-exact
package.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
也可以自定義很多配置的
最近組建了一個江西人的前端交流群,如果你是江西人可以加我微信?ruochuan12?私信 江西?拉你進群。
推薦閱讀
整整4個月了,盡全力組織了源碼共讀活動~
我歷時3年才寫了10余篇源碼文章,但收獲了100w+閱讀
老姚淺談:怎么學JavaScript?
我在阿里招前端,該怎么幫你(可進面試群)
·················?若川簡介?·················
你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》10余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助1000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。
識別上方二維碼加我微信、拉你進源碼共讀群
今日話題
略。分享、收藏、點贊、在看我的文章就是對我最大的支持~