前兩天的文章,我們分別使用 ESLint 跟 Prettier 作為靜態分析的工具。今天,我們將爲靜態分析做個收尾。
雖然可以在 VSCode 安裝及設定 Prettier Formatter for Visual Studio Code 存擋自動排版功能,但團隊難以強迫也無法強迫所有共同開發專案的人都使用。
我們可以在 package.json
新增一個 script
叫 check-format
,檢查所有該 format 的檔案是不是都已經 format 了。在 prettier
後面加 --list-different
flag,程式碼若未符合排版標準則會拋出錯誤:
package.json
{
...
"scripts": {
...
"lint": "eslint --ignore-path .gitignore .",
"format": "prettier --ignore-path .gitignore --write \"**/*.+(js|json)\"",
"check-format": "prettier --ignore-path .gitignore --list-different \"**/*.+(js|json)\"",
}
}
format
跟 check-format
有重複的 script 可以提取出來。在 package.json
新增一個 script
叫 prettier
,將重複的程式碼 prettier --ignore-path .gitignore \"**/*.+(js|json)\"
搬進去,其他有用到這段的 script 改成 npm run prettier --
後面加上所需的 flag, --
代表告訴 npm 要把後面帶的 flag 傳遞進去前面呼叫的 script。 package.json
現在改寫成:
{
...
"scripts": {
...
"lint": "eslint --ignore-path .gitignore .",
"prettier": "prettier --ignore-path .gitignore \"**/*.+(js|json)\"",
"format": "npm run prettier -- --write",
"check-format": "npm run prettier -- --list-different",
}
}
最後,在 package.json
新增一個 script
叫 validate
,組合 check-format
及 lint
:
{
...
"scripts": {
...
"lint": "eslint --ignore-path .gitignore .",
"prettier": "prettier --ignore-path .gitignore \"**/*.+(js|json)\"",
"format": "npm run prettier -- --write",
"check-format": "npm run prettier -- --list-different",
"validate": "npm run check-format && npm run lint"
}
}
安裝 Husky :
npm install husky --save-dev
在根目錄新增 .huskyrc
檔案,在 "pre-commit"
這裡加上要在每次 commit 前預先執行的 script:
{
"hooks": {
"pre-commit": "npm run validate"
}
}
如此一來,我們可以確保專案團隊成員每次 commit 之前,會預先檢查,在本地開發時已可先行修正。不用等到 CI 跑完之後才知道有錯誤。
如果有特殊情況要繞過 pre-commit 可以在下
git commit
指令的時候加上--no-verify
這個 flag
目前為止,你會發現一個小問題:每次 commit 前 husky 會先幫我們執行 npm run validate
,如果有 format 的錯誤,就會報錯,然後要手動下指令 npm run format
排版後,再 commit 一次。如果常常忘記先 format 好檔案,就會遇上這樣的問題,非常不方便。
幸好,我們可以搭配 lint-staged,在 pre-commit 的時候,可以幫我們針對這次想要 commit 的檔案,先做 format 或 lint。不用再手動另外下指令,而且,重點是:只會對這次 commit 裡相關的檔案有影響。
安裝 lint-staged:
npm install --save-dev lint-staged
在根目錄新增 .lintstagedrc
檔案,配置設定。下面的配置跟目前的 npm run lint
及 npm run format
做的事情是一樣的:
.lintstagedrc
{
"*.js": [
"eslint"
],
"**/*.+(js|json)": [
"prettier --write"
]
}
雖然
"prettier --write"
會更動到檔案,但lint-staged
會自動將檔案再次 add 到 Stage,所以不用加"git add"
調整 .huskyrc
檔案,讓 pre-commit 的時候改成執行 "lint-staged"
:
.huskyrc
{
"hooks": {
"pre-commit": "lint-staged"
}
}
大功告成!
最後,如果有個任務像下面這樣,要執行三個 script,但這些任務其實不需依序執行的話,可以使用 npm-run-all 同時執行,節省時間:
"example": "npm run check-format && npm run lint && npm run build"
安裝 npm-run-all :
npm install npm-run-all --save-dev
修改 package.json
檔案的 script,改為 npm-run-all
加上 --parallel
flag :
{
...
"scripts": {
...
"example": "npm-run-all --parallel check-format lint build"
}
}
靜態分析的部分已告一段落,我們使用 ESLint 及 Prettier 做為靜態檢查工具,搭配 Git Hooks 及 Husky 等相關工具,讓專案的靜態檢查自動化,增加專案開發一致性,且維持團隊開發品質。