husky – npm
lint-staged – npm
huskyはGitのフックのほぼ全てをpackage.json上で定義できるパッケージです。フックできない部分はいずれもGitリポジトリを管理するサーバサイド用フックのみです。huskyのインストールと使い方は次の引用の通りです。
Install
npm install husky --save-dev// package.json { "husky": { "hooks": { "pre-commit": "npm test", "pre-push": "npm test", "...": "..." } } }
複数コマンドを実行するときはtypicode/husky: 🐶 Git hooks made easy#multiple-commandsにある様に、コマンド間を&&で区切るcmd && cmd
かhusky個別の設定ファイルを用意します。すべてをpackage.jsonで完結させつつも、コマンドを&&で無理やり繋げない小技にnpm-run-all – npmを用いるやり方があります。次の様にあらかじめ小さいスクリプトを定義してnpm-run-allを介してまとめてhuskyで呼び出します。
{ "scripts": { "php-cs-fix": "./vendor/bin/php-cs-fixer fix -vvv", "eslint": "./node_modules/.bin/eslint resources/**/*.{ts,js,vue} --fix", "php-unit-test": "php ./vendor/phpunit/phpunit/phpunit --configuration phpunit.xml tests/Unit --teamcity", "pre-commit": "npm-run-all eslint php-cs-fix", "pre-push": "npm-run-all php-unit-test" }, "husky": { "hooks": { "pre-commit": "npm run pre-commit", "pre-push": "npm run pre-push" } } }
huskyだけでもコミット前のスクリプト起動漏れを防げて楽ですが、コミットのたびにフルでlintが走る上にlintで修正された分はコミット内容に含まれません。lint-stagedでこの問題を解決できます。
lint-staged – npm
lint-stagedはコミット用にステージングされたファイルの内、globで特定した対象のファイルについてのみ特定のコマンドを実行するパッケージです。対象ファイルはglob形式で指定します。大体*.{拡張子A,拡張子B}の様に指定するだけです。test絡みで通常のlintの対象にしたくない場合は!(*test).jsの様に!()を使います。!(*test).jsならばhogehoge.jsはlint, hogehoge.test.jsはnot lint。
lint-staged実例として次のような設定をし、Hoge.jsとFoo.phpファイルをコミットしようとするとします。
{ "lint-staged": { "*.{js,ts,vue}": [ "eslint --fix", "git add" ], "*.php": [ "php ./vendor/bin/php-cs-fixer fix -vvv --config .php_cs", "git add" ], "*.{json,css,scss}": [ "prettier --write", "git add" ] } }
その様な場合、まず”*.{js,ts,vue}”の表現にマッチしたHoge.jsを引数として”eslint –fix Hoge.js”, “git add Hoge.js”が実行されます。Hoge.jsがESLintの自動修正によって修正され、Hoge.js全体がコミット対象になるわけです。これでコミット前に自動でlintが走り、lintの修正結果もコミット内に反映されます。Foo.phpでもphp-cs-fixerで同様にlintによる修正がかけられ、両方が終わった後に改めてコミットされます。
husky, lint-staged, 各Linterを導入してpackage.jsonに次の様な記述を加えるとコミットのたびにLintが便利な形で走ってくれます。
{ "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.{js,ts,vue}": [ "eslint --fix", "git add" ], "*.php": [ "php ./vendor/bin/php-cs-fixer fix -vvv --config .php_cs", "git add" ], "*.{json,css,scss}": [ "prettier --write", "git add" ] } }