【Node.js】フォーマッター・リンターをコミット時に実行する(パッケージ非依存)
はじめに
Node.jsプロジェクトの品質を保つためコミット時にフォーマッターやリンターをかけるのを強制したい時、husky・lint-stagedを使用する例が散見されます。ですが、この目的のためだけに依存関係を増やしたくない場合もあるでしょう。
この記事では、これらのパッケージに依存することなくpre-commitフックを共有し、Prettierとリンターをコミット時に必ず実行させる方法を紹介します。
やり方
-
.githooks/pre-commit
ファイルをつくり次のように記載する
.githooks/pre-commit#!/bin/sh FILES=$(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g') [ -z "$FILES" ] && exit 0 npm run lint \ && echo "$FILES" | xargs ./node_modules/.bin/prettier --ignore-unknown --write \ && echo "$FILES" | xargs git add
-
[Linux/macOS]
.githooks/
ディレクトリ内のファイルに実行権限を付与するchmod +x .githooks/*
-
package.json
に次の行を追記する
package.json{ "scripts": { + "postinstall": "git config --local core.hooksPath .githooks" } }
-
installを行う
npm install
-
ステージしてコミット
git add --chmod=+x -- .githooks/
git add -- package.json
git commit
説明
.git
配下のファイルなどはgit管理されません。そのため、Gitのバージョン2.9より追加されたhooksの置き場を任意に指定できる機能を使い、.githooks
ディレクトリを使用するようにします。
このディレクトリは任意の名前にして問題ありません。ただし、ファイル名は一致させる必要があります。
#!/bin/sh
FILES=$(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g')
[ -z "$FILES" ] && exit 0
npm run lint \
&& echo "$FILES" | xargs ./node_modules/.bin/prettier --ignore-unknown --write \
&& echo "$FILES" | xargs git add
Prettierのドキュメントを参考にしています。
https://prettier.io/docs/en/precommit.html#option-6-shell-script
FILES=$(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g')
ステージ上にあるファイルの一覧を取得し、変数に入れています。
npm run lint
package.json
にlint
スクリプトが記載されている前提のコードとなっています。
eslintを使用している場合は次のようにするとよいでしょう。
./node_modules/.bin/eslint --cache .
echo "$FILES" | xargs ./node_modules/.bin/prettier --ignore-unknown --write
前述した一覧を渡すことで、ステージ上にあるファイルのみフォーマットされるようにしています。
echo "$FILES" | xargs git add
ここまでの処理による変更をステージ上に反映させます。
これらを&&
で繋ぐことで、lintエラーが出たりフォーマットが失敗したりした段階でコミットが中止されるようにしています。
"postinstall": "git config --local core.hooksPath .githooks"
postinstall
スクリプトはインストールが終わった後に実行されます。
このときに、gitのフックのパスを先ほど作成したフォルダにしその配下のスクリプトが使われるように変更しています。
Discussion