これはなに
husky + lint-staged でコミット前にLinterを実行し、通らない場合はコミットできないようにする設定方法を記す。
仕組み
- git-hookをhuskyでハンドリングし、pre-commitのフックを利用して、コミット時に必ず
yarn lint-staged
を実行させる yarn lint-staged
でLinterを実行させるように、package.jsonにスクリプトを定義する
設定のしかた
必要なパッケージをインストールする。
yarn add -D husky lint-staged
husky-initコマンドを実行する。 実行するコマンドの詳細はhuskyの公式サイト を参照すること。 Yarn version 1の場合は下記になる。
npx husky-init && yarn
.gitディレクトリとpackage.jsonのファイルが同一階層にない場合は、下記のようなエラーが発生する。
$ npx husky-init && yarn
Need to install the following packages:
husky-init@8.0.0
Ok to proceed? (y) y
husky-init updating package.json
setting prepare script to command "husky install"
/root/.npm/_npx/1ab9c0f68ac2536e/node_modules/husky/lib/index.js:22
throw new Error(`.git can't be found (see ${url})`);
^
Error: .git can't be found (see https://typicode.github.io/husky/#/?id=custom-directory)
at install (/root/.npm/_npx/1ab9c0f68ac2536e/node_modules/husky/lib/index.js:22:15)
at Object.<anonymous> (/root/.npm/_npx/1ab9c0f68ac2536e/node_modules/husky-init/lib/bin.js:16:21)
at Module._compile (node:internal/modules/cjs/loader:1218:14)
at Module._extensions..js (node:internal/modules/cjs/loader:1272:10)
at Module.load (node:internal/modules/cjs/loader:1081:32)
at Module._load (node:internal/modules/cjs/loader:922:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:82:12)
at node:internal/main/run_main_module:23:47
Node.js v19.3.0
このエラーへの対処法は、huskyの公式サイト に書かれているとおりで、 package.jsonに追加されているprepareスクリプトを変更する。
app/package.json
{
"scripts": {
- "prepare": "husky install"
+ "prepare": "cd .. && husky install app/.husky"
},
}
再度yarnコマンドを実行する。
yarn
成功すると、.husky
ディレクトリが生成される。
ここにpre-commitファイルを作成する。
npx husky add .husky/pre-commit ""
作成されたpre-commitファイルに、lint-staged(とその他実行したいスクリプト)を実行するコマンドを追記する。
.gitディレクトリとpackage.jsonのファイルが同一階層にない場合は、package.jsonのある階層に移動するコマンド(cd app
)も追記する。
app/.husky/pre-commit
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
cd app # package.jsonのある階層に移動する
yarn lint-staged # これを必ず書く
yarn build # ほかに実行したいスクリプトがあれば追記する
最後に、package.jsonにlint-stagedスクリプトとlint-staged
実行時のlintコマンドを追記する。
下記はVueプロジェクトの例。
lint-staged
でESLint, StyleLint, Prettierを実行させている。
app/package.json
{
"scripts": {
"lint-staged": "lint-staged"
},
"lint-staged": {
"*.{vue,js,jsx,cjs,mjs,ts,tsx,cts,mts}": "eslint --fix",
"*.{css,scss,vue}": "stylelint --fix",
"*": "prettier -w -u"
},
}
以上で、コミット時にLinterが実行され、エラーの場合はコミットされないようになる。