做 lint 、 format 或是通過測試,對於程式碼的品質維護有很大的幫助,因此在提交代碼時,我們會使用 Git hooks 確保這些優化程序有被執行。
但是在 Git hooks 執行這些優化時,程序處理的範圍會包含整個專案的程式碼,就算是未提交的檔案,依然會被作為優化對象,這樣一來會浪費許多時間。
lint-staged 是個 npm 套件,它會依照配置將符合規則( glob )的 Git 暫存檔案路徑帶入設定的程序中並執行。
lint-staged 的目的就是讓這些優化程序只作用於提交的程式碼上,進而減少花費的時間。
用 npm 安裝 lint-staged :
npm install lint-staged --save-dev
使用前需要建立配置檔 lint-staged.config.js
:
module.exports = {
'*': ['echo'],
};
為了解說 lint-staged 的功能,這裡將所有提交的檔案都以 echo
輸出參數資訊。
接著將檔案加入暫存區中:
git add package.json package-lock.json
然後執行 lint-staged
指令:
npx lint-staged -v
lint-staged 預設不輸出程序的訊息,為了觀看 lint-staged 的功能,要加上參數 -v
,它會顯示程序所輸出的訊息。
執行的結果如下:
> lint-staged -v
✔ Preparing...
✔ Running tasks...
✔ Applying modifications...
✔ Cleaning up...
ℹ echo:
/Users/PeterChen/Documents/code/build-a-super-comfortable-web-dev-env/days/11-lint-staged/examples/example-lint-staged/package-lock.json /Users/PeterChen/Documents/code/build-a-super-comfortable-web-dev-env/days/11-lint-staged/examples/example-lint-staged/package.json
進入暫存的的檔案 package.json
與 package-lock.json
被作為參數傳入程序中,並被 echo
輸出。
lint-staged 設定的每個規則的鍵值為 glob 的字串, lint-staged 會將包含在內的檔案轉為絕對路徑( absolute path )並作為參數傳入各個指令內。
例如下面這個例子:
module.exports = {
'*.js': ['echo'],
};
這樣的配置會只讓 JS 檔案被 echo
輸出路徑,例如 lint-staged.config.js
就會被包含,但是 package.json
因為不是 .js
的檔案,所以就算提交了還是不會被 echo
輸出。
有時在同個檔案上,我們不只要使用 linter 檢查語法的問題,還要使用 formatter 格式化,甚至執行測試確認通過。
lint-staged 可以設置陣列,讓複數指令作用於相同的檔案上。
以下面的例子來說:
module.exports = {
'*': ['echo', 'cat'],
};
它會對所有的提交的檔案執行 echo
與 cat
。
藉由與 Husky 的整合,在提交前確保程式碼的品質,讓開發者可以:
git commit
時自動啟用 lint 、 format 與測試。為了在提交代碼時可以觸發各種檢查工具,我們需要將 lint-staged 藉由 Husky 配置到 Git hook 上:
npx husky add .husky/pre-commit 'npx lint-staged'
然後重新註冊 Git hooks :
npm install
npm install
會觸發在執行 husky-init
時建立的 prepare
script ,去做相關的初始化工作。
如果需要 Husky 相關的使用說明,請看「 20 - Husky - Git Hooks 工具」的介紹。
這樣一來,每當我們提交代碼時,就會叫用 npx lint-staged
把提交的檔案路徑送去給 lint-staged 中設定指令做處理。
為了讓 lint-staged 可以對於各類型的檔案提供合適的工具做處理,我們需要設定 lint-staged.config.js
:
module.exports = {
'package.json': ['prettier --write'],
'*.js': ['npx eslint --fix', 'prettier --write'],
'*.css': ['stylelint --fix', 'prettier --write'],
'*.md': ['markdownlint', 'prettier --write'],
};
藉由 glob 設定各個檔案類型應該被哪些工具檢查,藉以避免不必要的花費與衝突產生。
git commit
的時候叫用 lint-staged ,接著在 lint-staged 中針對各種不同的檔案類型設置對應的處理工具,如此一來,可以減少工具因不符合的檔案而進行無用的處理,也可以降低衝突的產生。