用 Husky和Iint-Staged 構(gòu)建代碼檢查工作流
前言
一個(gè)項(xiàng)目如果涉及到多人協(xié)作,由于每個(gè)人代碼的書(shū)寫(xiě)習(xí)慣和風(fēng)格不太一樣,如果沒(méi)有統(tǒng)一的規(guī)范,那就會(huì)很亂,這對(duì)代碼的可維護(hù)性大大降低。
所以現(xiàn)代工程有個(gè)一環(huán)節(jié)就是代碼風(fēng)格檢查(Code Linting,下面以 Lint 簡(jiǎn)稱(chēng)),來(lái)保障代碼規(guī)范一致性
現(xiàn)在也有很多保障代碼規(guī)范一致性,比如:ESLint、prettier、SCSSLint、JSONLint 等。比較全的可以見(jiàn) github 官方的 Lint 工具列表[1]
本文不會(huì)介紹每一個(gè)工具怎么用,而是介紹怎么把這些工具串起來(lái),構(gòu)建一個(gè)代碼檢查的工作流。
最簡(jiǎn)單的方法
最簡(jiǎn)單的方法就是自己每次在 commit 代碼之前先處理一下,以 eslint 舉例:
eslint src/**/*.js
git add .
git commit -m 'feat: 一個(gè)新 feature'
這種方法有兩個(gè)致命的缺點(diǎn):
- 如果檢測(cè)工具多,需要多次處理。
- 很容易遺忘。
通過(guò) scripts 來(lái)解決如果檢測(cè)工具多,需要多次處理scripts 就是 package.json 里的 scripts。
比如你同時(shí)需要用到 prettier 和 eslint,可以定制一個(gè)腳本,然后運(yùn)行這個(gè)腳本之后再提交代碼:
{
"scripts": {
"lint": "prettier --write & eslint src/**/*.js"
}
}
然后每次提交代碼前就只需要:
npm run lint
git add .
git commit -m 'feat: 一個(gè)新 feature'
通過(guò) husky(哈士奇)來(lái)解決容易遺忘的問(wèn)題
雖然咱們通過(guò) scripts 來(lái)解決檢查工具多的問(wèn)題,但是還有一個(gè)容易遺忘怎么解呢?
解決方案就是通過(guò) husky,原理實(shí)際上是通過(guò) git hooks[2] 來(lái)解決,husky 就是讓 git hooks 用起來(lái)更容易的工具。
You can use it to lint your commit messages , run tests , lint code , etc... when you commit or push. Husky supports all Git hooks[3].
”這個(gè)是 husky 官網(wǎng)的一句話(huà),用來(lái)描述 husky 可以做什么。
那到底怎么解決呢?接下來(lái)介紹一下 husky 的使用方式:
1. 安裝
安裝 husky
npm install husky --save-dev
啟用 git hooks
npx husky install
執(zhí)行完之后文件根目錄會(huì)多一個(gè) .husky 文件夾:
在安裝后自動(dòng)啟用 git hooks
npm set-script prepare "husky install"
然后你可以看到 package.json 里增加一個(gè) script
// package.json
{
"scripts": {
"prepare": "husky install"
}
}
注意一個(gè)點(diǎn):yarn 安裝是不支持 prepare 這個(gè)生命周期的,需要將 prepare 改成 postinstall。具體可以見(jiàn)官網(wǎng)[4]
2. 創(chuàng)建一個(gè) precommit hook
npx husky add .husky/pre-commit "npm run lint"
git add .husky/pre-commit
執(zhí)行完之后在 .husky 目錄下會(huì)多一個(gè) pre-commit 的文件,里面的 npm run lint 就是這個(gè) hook 要執(zhí)行的命令,后續(xù)要改也可以直接改這個(gè)文件。
這個(gè)時(shí)候 commit 就會(huì)先自動(dòng)執(zhí)行 npm run lint 了,然后才會(huì) commit。
但是這樣解決了以上的問(wèn)題,當(dāng)項(xiàng)目大的時(shí)候會(huì)遇到一些問(wèn)題,比如每次 lint 是整個(gè)項(xiàng)目的文件,文件太多導(dǎo)致跑的時(shí)間過(guò)久,另外如果這個(gè) lint 是在項(xiàng)目后期接入的話(huà),可能 lint 命令會(huì)報(bào)很多錯(cuò)誤,全量去改可能會(huì)有問(wèn)題。
lint-stadge 只 lint 改動(dòng)的
基于上面的痛點(diǎn),lint-stadge 就出現(xiàn)了,它的解決方案就是只檢查本次提交所修改(指 git 暫存區(qū)[5]里的東西)的問(wèn)題,這樣每次 lint 量就比較小,而且是符合我們的需求的。
如果不知道暫存區(qū)的需要去復(fù)習(xí)一下 git 知識(shí),簡(jiǎn)單來(lái)說(shuō)就是 git add 或者 git commit -a 的那部分代碼會(huì)先放到暫存區(qū)。
lint-staged 用法如下:
1. 安裝
npm install -D lint-staged
2. 修改 package.json 配置
{
"lint-staged": {
"src/**/*.js": "npm run lint"
}
}
3. 設(shè)置 precommit 為運(yùn)行 lint-staged
在完成上面的配置之后,可以手動(dòng)通過(guò) npx lint-staged 來(lái)檢查暫存區(qū)里面的文件。
手動(dòng)是永遠(yuǎn)不會(huì)手動(dòng)的,自動(dòng)的方法就是將 npx lint-staged 設(shè)置到 hook 里。
npx husky add .husky/pre-commit "npx lint-staged"
或者直接去改 .husky 下面 precommit 的文件。
到現(xiàn)在我們的代碼檢查工作流就完成了。在 git commit 的時(shí)候就自動(dòng)的回去幫我們跑檢查腳本,而且還是只針對(duì)我們本次提交的代碼進(jìn)行檢查。
參考配置
react + less 項(xiàng)目 lint-staged 的配置可以參考:
{
"lint-staged": {
"**/*.less": "stylelint --syntax less",
"**/*.{js,jsx,ts,tsx}": "eslint --ext .js,.jsx,.ts,.tsx",
"**/*.{js,jsx,tsx,ts,less,md,json}": [
"prettier --write",
"git add"
]
}
}
總結(jié)
本文筆者沒(méi)有去詳細(xì)介紹每個(gè) lint 工具的使用和配置,也沒(méi)有直接給一個(gè)構(gòu)建代碼檢查工作流的最佳實(shí)踐,而是一步一步從最原始到使用 git hooks、husky、lint-staged 各種工具來(lái)推導(dǎo)出最后的方案。
因?yàn)槲矣X(jué)得如果不把每個(gè)工具用來(lái)解決什么問(wèn)題,為什么需要它說(shuō)清楚,而是直接給一個(gè)最佳實(shí)踐的 SOP,這樣會(huì)成為一個(gè)無(wú)腦 copy 的執(zhí)行者,當(dāng)哪天找不到這篇文章的時(shí)候自己可能無(wú)從下手了,但是當(dāng)你知道了自己遇到什么問(wèn)題,應(yīng)該怎么去解決之后,自己也可以從 0 配置一份出來(lái)。
參考
- 用 husky 和 lint-staged 構(gòu)建超溜的代碼檢查工作流[6]
- husky 官網(wǎng)[7]
參考資料
[1]Lint 工具列表:
??https://github.com/collections/clean-code-linters??
[2]git hooks:
??https://git-scm.com/book/zh/v2/%E8%87%AA%E5%AE%9A%E4%B9%89-Git-Git-%E9%92%A9%E5%AD%90??
[3]all Git hooks:
??https://git-scm.com/docs/githooks??
[4]官網(wǎng):
??https://typicode.github.io/husky/#/?id=yarn-2??
[5]git 暫存區(qū):
??https://www.4e00.com/git-zh/1-introduction.html#-ReHMS4ux??
[6]用 husky 和 lint-staged 構(gòu)建超溜的代碼檢查工作流:
??https://segmentfault.com/a/1190000009546913??
[7]husky 官網(wǎng):