husky: 借助 Git Hooks 提升你提交的代碼質(zhì)量

有很多工具可以自動化我們的代碼任務(wù),比如:使用 ESLint 檢查語法問題、使用 Prettier 格式化代碼。但并不是團隊中的每個人都會記得在每次提交時運行這些命令,而不運行這些指令有可能造成某些協(xié)作或代碼問題,這就是 husky 的能力所在—— 通過注冊 Git Hook的方式幫助我們在項目流水線上插入一些中間處理邏輯,比如檢查你的提交信息,運行測試,檢查代碼等.……
什么是 Git Hooks?
Git Hooks 是一種腳本,可以在 Git 生命周期的特定事件中運行。這些事件包括提交的不同階段,例如提交之前(pre-commit)和提交之后(post-commit)。
Git Hooks 非常有用,允許開發(fā)人員運行自定義的代碼任務(wù),甚至可以通過自動化其他腳本來執(zhí)行這些任務(wù)以強制執(zhí)行某些標準規(guī)范。
什么是 husky?
husky 是一個工具,允許我們輕松地管理 Git Hooks 并在這些階段運行我們想要的腳本。
它通過項目中的 .husky
目錄中的文件工作,配置 husky 來運行我們指定的腳本。之后,由 husky 負責管理在 Git 生命周期階段中我們腳本的運行了。
實戰(zhàn)練習
我們將建立一個簡單的項目測試 Git Hooks。為了方便,我將選擇 Next.js 創(chuàng)建項目,并使用 Prettier 演示 Git Hooks 的功能。
為了測試 Git Hooks, 我們將添加一個簡單的命令行語句來查看 husky 是否正常工作。但我們還將嘗試添加 Prettier——Prettier 是一個工具,用于自動格式化我們的代碼。而借助 Next.js,你可以在不做任何意外更改的情況下進行測試。
撰寫本文時,husky 目前版本是 v8,我們會基于最新的這個版本測試。
第 0 步:創(chuàng)建項目
瀏覽器訪問:http://localhost:3000,成功創(chuàng)建好了項目。

第 1 步:安裝 husky
husky 即可以手動也可以自動安裝(pnpm dlx husky-init && pnpm install)。不過,為了達到學習目的,我們采用手動安裝的方式。
1.?安裝 husky
2. 配置 Git Hooks
3.?每次 install 后/ publish 前自動檢查 husky Git Hooks 的配置,編輯 package.json
文件
第 2 步:如何配置 husky 來運行 Git Hooks
husky 支持幾乎所有由 Git 定義的 Git Hooks,因此我們可以在 Git 事件流中非常靈活地進行操作。
husky 使用 husky add <file> [cmd]
(不要忘記在此之前運行 husky install
)指令添加 Hook。
上述我們定義了pre-commitHook,會在每次提交(git commit)前執(zhí)行npm test腳本。
提交修改:
查看執(zhí)行效果。

可以看到,我們成功的在提交前執(zhí)行了 npm test
腳本!另外,如果 npm test
執(zhí)行失敗,提交會自動中止,這有效保證了我們提交的有效性。
當然,不止 pre-commit
,常用的還有 pre-push
,就是在推送到遠程倉庫前要做的事情。篇幅限制,這里就不多贅述了,大家可以自行實驗。我這里簡單舉個例子。
第 3 步:如何使用 husky 和 Prettier 格式化代碼
真實項目中,為了風格統(tǒng)一,往往會使用 Prettier 來自動格式化代碼。而 Prettier 就是這樣一款工具,可以讓你輕松地格式化代碼,讓代碼看起來像是由一個人編寫的,避免協(xié)作上的心智負擔。
提醒:運行 Prettier 將自動格式化你的所有代碼,一旦將其應(yīng)用為 Git Hook,它將自動化這個過程。
首先安裝 Prettier 依賴,package.json
中添加 format
scripts:?
prettier --write .
會原地原地格式化文件。執(zhí)行 npm run format
,會看到有修改的文件:

目前 husky 運行我們的 Prettier 命令時,我們只是格式化代碼,沒有將將這些更改保存為 Git 流程中的一部分。因此,我們還要使用git add來存儲所有這些更改,將它們包含在提交中。
現(xiàn)在我們來測試下提交。
看下執(zhí)行結(jié)果:

當我們運行提交命令后,可以看到 husky pre-commit
Hook 已經(jīng)生效,并且格式化了我們的代碼,而且格式化的代碼,也作為本次提交的內(nèi)容提交了!

我接下來可以做什么?
使用 lint-staged 僅對更改的文件運行格式化
我們在 pre-commit
鉤子中使用 Prettier,并指定 . 表示每次運行都會作用在所有文件上。
我們還可以使用一個叫做 lint-staged 的工具,它允許我們?nèi)匀煌ㄟ^ husky 運行 Git Hooks,但只會作用于暫存文件。就像它的介紹——“ Run linters on git staged files”。如果我們想要用 husky 和 Prettier 來實現(xiàn)這個功能,配置類似下面這樣:
首先修改 .husky/pre-commit
,讓 lint-staged 接管代碼格式化:
修改 package.json
文件,增加 lint-staged
字段:
Prettier 配置
Prettier 是支持配置自定義的,你可以通過 .prettierrc.json 自定義格式化的規(guī)則,或者通過 .prettierignore 忽略某些文件。類似下面這樣:
.prettierrc.json
:
overrides
字段用于支持針對特定文件規(guī)則的覆蓋。
.prettierignore
:
移除 husky
除非你更換工具,否則這一步不會做。
從package.json中刪除"prepare": "husky install",
執(zhí)行下面的語句即可:
需要留意的是,我們要恢復 core.hooksPath
的配置(由 .husky
變?yōu)槟J的 .git/hooks
)。
參考鏈接
https://www.freecodecamp.org/news/how-to-add-commit-hooks-to-git-with-husky-to-automate-code-tasks/#step-2-configuring-husky-to-run-git-hooks
https://typicode.github.io/husky/getting-started.html
https://github.com/typicode/husky/tree/main
https://nextjs.org/docs/getting-started/installation
https://docs.npmjs.com/cli/v6/using-npm/scripts#prepare-and-prepublish