項(xiàng)目中使用Husky 格式化代碼和校驗(yàn) Commit 信息
大家好,我是前端西瓜哥。今天我們學(xué)習(xí)使用 husky 工具,在 commit 的時(shí)候做一些風(fēng)格的校驗(yàn)工作,包括 commit 信息格式化和文件格式化。
git hook 和 husky
git hook 讓我們可以在 git 執(zhí)行一些行為的前后時(shí)機(jī),執(zhí)行一些腳本。
比如 pre-commit? ,能夠在我們真正提交 commit 之前先執(zhí)行一段代碼,如果這段代碼報(bào)錯(cuò)(exit 1),提交會(huì)被取消;如果正常執(zhí)行,commit 會(huì)被真正提交。
或是 commit-msg,也能在真正 commit 前拿到 commit 信息內(nèi)容,去做一些檢驗(yàn)工作。
利用 git hook 的能力,我們就可以在 commit 前做一些風(fēng)格檢驗(yàn)或格式化,比如 ESLint、Prettier、commit 格式等。
git hook 是 sh 腳本,在項(xiàng)目 .git/hooks 目錄下。這有一個(gè)比較尷尬的問(wèn)題:.git 下的文件是不會(huì)被 git 提交的。husky 就是解決這個(gè)問(wèn)題的一個(gè)方案。
實(shí)際上 git 2.9 之后,我們可以通過(guò)配置 git 的 core.hookspath 來(lái)指定 hook 目錄為相當(dāng)項(xiàng)目下的目錄,理論上可以不用 husky。
但 husky 還是算是做了一層封裝,可以更好地操作 hook,比如通過(guò)命令行快速生成 hook,并將其設(shè)置為可執(zhí)行。
husky 4 及以前使用的是 .huskyrc 來(lái)進(jìn)行配置。那時(shí)候設(shè)計(jì)上有一些問(wèn)題,就是沒(méi)有配置的 hook 也會(huì)觸發(fā)鉤子執(zhí)行。于是在 husky 4 做了破壞性的修改。使用方法變成了在 .husky 目錄下直接加鉤子腳本。
husky 安裝和啟用
不講解 husky 4 及其以前版本的使用,因?yàn)橐呀?jīng)過(guò)時(shí)了。
首先是安裝:
然后執(zhí)行 husky 命令行工具,啟用 git hook:
該命令會(huì)創(chuàng)建一個(gè) .husky 目錄。
同時(shí),該命令還將 git 所在項(xiàng)目本地環(huán)境的 core.hookspath? 設(shè)置為 .husky?。所以,這個(gè) .husky 目錄就是我們放 git hook 腳本的地方。
我們執(zhí)行下面命令,可以看到當(dāng)前 git 項(xiàng)目的本地配置有:core.hookspath=.husky。
其他同事拉取項(xiàng)目時(shí),他們可能會(huì)忘記執(zhí)行上面的命令啟用 git hook。但有一個(gè)命令他們是一定會(huì)執(zhí)行的,就是執(zhí)行 npm install? 或 yarn 去安裝依賴(lài)。
于是我們需要利用 npm script 的生命周期腳本,加上一個(gè) prepare。prepare 會(huì)在 install 之后執(zhí)行。
這樣就能保證新同事拉項(xiàng)目并安裝依賴(lài)后,husky 被啟用。
創(chuàng)建 hook
該命令會(huì)給你在 .husky 下創(chuàng)建一個(gè) pre-commit 腳本,并填充 npm test 內(nèi)容,這樣我們就能在 commit 前先過(guò)一過(guò)測(cè)試用例。
這個(gè)腳本會(huì)自動(dòng)設(shè)置為可執(zhí)行。
如果你是手動(dòng)創(chuàng)建的,你需要手動(dòng)使用 chmod u+x pre-commit 命令將該文件設(shè)置為可執(zhí)行文件。否則鉤子腳本是不會(huì)執(zhí)行的。
創(chuàng)建的腳本內(nèi)容為:
它會(huì)在真正 commit 前執(zhí)行 npm test,如果報(bào)錯(cuò)就會(huì)中止 commit。
實(shí)戰(zhàn):使用 commitlint 校驗(yàn) commit 信息格式
我們希望在提交 commit 時(shí),能夠檢驗(yàn) commit 信息,如果不對(duì)就不允許提交。這樣能防止開(kāi)發(fā)人員提交一些雜亂、無(wú)法理解或不統(tǒng)一的信息。
這種情況下需要用到 commit-msg 鉤子,我們先創(chuàng)建一個(gè)沒(méi)有內(nèi)容的 commit-msg。
?在 commit-msg 腳本中,我們可以通過(guò) $1? 拿到提交信息。$1? 指向的是 .git/COMMIT_EDITMSG 文件,該文件保存著最后一次提交的 commit 信息。
可以拿到 commit 信息,那我們就可以在上面做一些校驗(yàn)工作,比如看是否符合 feat: xxx 的格式。這里有個(gè)問(wèn)題,就是我們需要自己去聲明一些規(guī)范,并且要自己去實(shí)現(xiàn)代碼。
那,我們?nèi)フ逸喿?,輪子找到了,它就?commitlint。commitlint 是一個(gè)命令行工具,能夠做 commit 的校驗(yàn),并提供了官方的校驗(yàn)規(guī)則,此外也支持你自己配置規(guī)則。
先安裝 commitlint:
然后創(chuàng)建 commitlint.config.js? 配置文件,并添加內(nèi)容,使用 @commitlint/config-conventional 。
@commitlint/config-conventional? 是一個(gè)經(jīng)典的 commit 規(guī)范,我們需要用類(lèi)似 feat: add util.js? 或 fix: fix wrong text 這樣的格式,具體文檔見(jiàn):
https://www.conventionalcommits.org/en/v1.0.0/。
然后我們?cè)?commit-msg 鉤子上加上:
- npx --no :表示只使用本地項(xiàng)目 node_modules 下的腳本,不允許找不到的時(shí)候嘗試去下載。下載耗費(fèi)時(shí)間,所以要取消,你要確保已經(jīng)把命令行工具下載好。
- commitment --edit <文件名>?:執(zhí)行 commitment 命令行工具,并使用--edit? 選項(xiàng),從一個(gè)文件里提取 commit 內(nèi)容來(lái)進(jìn)行校驗(yàn)。校驗(yàn)規(guī)則由前面說(shuō)的commitlint.config.js 配置文件來(lái)指定。
配置后,我們測(cè)試下,先提交不規(guī)范的 commit:
加上開(kāi)頭的 commit 類(lèi)別 type,再提交,成功了:
實(shí)戰(zhàn):使用 lint-staged 格式化要暫存區(qū)的文件
lint-staged 是一個(gè)命令行工具,它能夠?qū)?git 的 staged(暫存區(qū))中的文件使用 linter 工具格式化,修復(fù)一些風(fēng)格問(wèn)題,并再次添加到 staged 上。
一個(gè)經(jīng)典的搭配是,配合 husky 的 pre-commit 鉤子將文件 格式化后再提交。pre-commit 在真正 commit 前觸發(fā),配合上 lint-staged,就能做一些風(fēng)格的修正。
使用 lint-staged 強(qiáng)制提交的文件做格式化適用的場(chǎng)景:
- 一些團(tuán)隊(duì)成員使用的編輯器沒(méi)有或未安裝格式化插件,代碼不能在保存后自動(dòng)格式化,容易提交風(fēng)格錯(cuò)誤的代碼;
- 項(xiàng)目開(kāi)發(fā)了一段時(shí)間才引入了代碼風(fēng)格規(guī)范,希望一點(diǎn)點(diǎn)修正。如果一次性全部格式化,可能會(huì)有不少需要手動(dòng)修復(fù)的風(fēng)格;
下面我們開(kāi)始配置。
首先我們安裝 lint-staged:
然后新增 pre-commit 鉤子,內(nèi)容為 npx lint-staged:
因?yàn)樘峤坏奈募卸喾N類(lèi)型,比如 js、md、less、mdx 等。所以我們還需要配置一下,針對(duì)不同類(lèi)型文件使用不同的 linter。
lint-commit 的配置可以放到 package.json,也可以放到專(zhuān)門(mén)的配置文件里。我選擇后者,在項(xiàng)目根目錄創(chuàng)建一個(gè) .lintstagedrc.js 文件,然后加上以下內(nèi)容:
這里表示指定在 src 目錄下 js、jsx、ts、tsx 后綴文件,使用 eslint 做格式化。我只使用 eslint 做 js 和 ts 的格式化,其他的就不管了,你可以考慮用過(guò) prettier 格式化它們。
這里有一個(gè) Github 可以參考,地址為:
https://github.com/F-star/xigua-ui。
結(jié)尾
husky 是一個(gè)很有用的工具,能夠利用 git hook 在本地 commit 時(shí),配合 eslint 等 linter 工具做文件的格式化,并配合 commitlint 校驗(yàn) commit 信息格式,是工程化統(tǒng)一代碼風(fēng)格的一大利器。