見出し画像

ESLint・Prettierを併用してコードスタイルのチェックはPrettierにまかせてみた

はじめに

こんにちは、SHIFT の開発部門に所属している Katayama です。

Node.js(ES6 で実装)における ESLint・Prettier の設定を 1 からやってみたでは、以下のように書いていた通り、コードのスタイルルールは Prettier の設定にしつつも、ESLint にそのルールを組み込み、ESLint のチェック時にコードスタイルのエラーも表示されるようにしていた。

今回はフォーマットルールに沿っているか?も静的解析でチェックをしたい(ESLint のルールとして検証する構成にしたい)ので plugin:prettier/recommended を extends に入れる

このように設定すると、Integrating with Lintersで触れらているように、以下の画像の通りエディター(VS Code)上でスタイルのエラーが表示され、煩わしかったりした。

そこで今回は、ESLint のルールの内、Prettier のルールと競合するものを全て Off にした上で、コードのスタイルの修正(コードの自動整形)については Prettier に全て任せる設定をやってみた。

※今回は以下で取り上げている通り、Git hooksでpre-commitなどgit操作のイベントをトリガーにコードの自動整形を実行する仕組みを試します。こちらは、以下のような課題があるチームでは有益であり、開発者のエディターの差異や拡張機能のインストール不備があってもチーム全体で同じコード品質を実現でき、便利です。

・開発者間のエディターが違うので、ファイル保存時の自動整形をOnにできない(VS Codeであれば以下のような設定でPrettierによる自動整形ができるが、エディターが違えばそうはいかない)

// .vscode/settings.json
{
	...
	"editor.defaultFormatter": "esbenp.prettier-vscode",
	"editor.formatOnSave": true,
	...
}

・エディターにある拡張機能のインストール不備で、エディター機能による自動整形ができていなかった

Prettier のスタイルルールを ESLint に組み込む事の問題提起

この話についてはIntegrating with Lintersに書かれている通り、以下のような問題があると Prettier は主張している。

・You end up with a lot of red squiggly lines in your editor, which gets annoying. Prettier is supposed to make you forget about formatting – and not be in your face about it!(エディタに赤いジグザグ線がたくさん表示され、イライラしてしまいます。Prettier は書式設定のことを忘れさせてくれるものであり、また、書式設定に煩わされないものです)
・They are slower than running Prettier directly.(直接 Prettier を動かすより遅い)
・They’re yet one layer of indirection where things may break.(このように、物事が壊れる可能性のある間接的なレイヤーがまだ 1 つあるのです)

上記の主張通り、結論として Prettier としては、基本的には ESLint と Prettier は分けて使われるべき(コードのスタリングに関しては Prettier が担うべきで ESLint がスタイル以外の静的解析に専念すべし)という考え方をしている。

実際に設定してみる

ESLint のルールの内、Prettier のルールと競合するものを Off にする

スタイルに関する部分は Prettier に全て任せるようにするには以下のように".eslintrc.json"を設定すればいい。

$ yarn add --dev eslint-config-prettier
// .eslintrc.json
{
	...
	"extends": [
		...
		"prettier" // <- extendsの末尾に記載するのがポイント
	],
	...
}

このようにする事で、Prettier のスタイルルールと衝突するルールが Off になり、ESLint のチェックでコードのスタイルに関するエラーが出なくなる。

※ちなみに、eslint-config-prettier を継承するとindex.jsに書かれているルールが継承される(自身の.eslintrc.json のルールに設定されている事にする)が、中身としてはいくつかのルールを Off にしているだけ。

Prettier のルールで自動整形する

Git hooks の仕組みを使えばよい(Git hooks については8.3 Git のカスタマイズ - Git フックを参照)。具体的にはsimple-git-hooksを利用し、これにより"git commit"時に(正確には Git hooks の pre-commit フックで)自動でコードのスタイル修正(自動整形)を走らせるようにする。

$ yarn add --dev simple-git-hooks
// package.json
{
    ...
	"scripts": {
		...
		"prepare": "npx simple-git-hooks"
	},
	"simple-git-hooks": {
		"pre-commit": "npx prettier --write"
	}
}

package.json の中身について 1 点補足する。

・prepare
今回は simple-git-hooks の git hooks を設定するためにnpx simple-git-hooksを実行する必要があり(Add simple-git-hooks to the projectの 3 のUpdate ./git/hooksの部分に書かれている通り)、それを他の人がこのプロジェクトを利用する際に"npm install"または"yarn install"時に自動で設定されるようにするために書いている

※今回は prepare の"Runs on local npm install without any arguments"の機能で"npx simple-git-hooks"を実行している。prepare 自体についてはLife Cycle Scriptsを参照(yanr の場合も v1 ではscriptsに書かれているのでサポートしているようだが、v2 ではLifecycle Scriptsに書かれているもののみのサポートになっているので prepare は使えない模様)。

このようにする事で、以下の動画のように"git commit"時に Prettier による自動整形が走るようになる。

ただ、上記の動画を見て分かる通り、git commit の対象以外のファイル全てに対して"npx prettier --write"が走っており無駄がある…。そして"npx prettier --write"を実行したものが git commit に含まれずに新しい diff になってしまっている。これでは使いにくいので、staged になったファイルのみを対象にして"npx prettier --write"が走るようにし、修正したものがそのままコミットされるように設定していく。

$ yarn add --dev lint-staged
package.json{
	...
	"scripts": {
		...
		"prepare": "npx simple-git-hooks"
	},
	"lint-staged": {
		"*": "npx prettier --ignore-unknown --write"
	},
	"simple-git-hooks": {
		"pre-commit": "npx lint-staged"
	}
}

package.json の中身について 2 点補足する。

・lint-staged
 これは公式に

Run linters against staged git files(ステージングされた git ファイルに対してリンターを実行する)

と書かれている通り、ステージング済みのファイルのみに対しコマンドを実行できるようにするためのもの(詳細はlint-stagedを参照)。これにより今まで全てのファイルに対して"npx prettier --write"を実行してたが、その対象ファイルをステージングされているファイルのみに限定でき、効率的にコードの自動整形ができる

・npx prettier --ignore-unknown --write
 --ignore-unknownオプションを付けているがこれは、以下の動画のように Prettier のルールがない形式のファイルがあると "[error] No parser could be inferred for file: yarn.lock" というエラーが出るので、Prettier のルールが未定義のもを無視するために付けている("npx lint-staged"はストレージ済みのファイル全てに対して"npx prettier --write"を実行するので、"npx prettier --write ."の時と違い、Prettier 側でフォーマッティング未対象のファイルを無視するような動きにはならないので注意)

この設定をした上で再度 git commit を行うと以下の動画の通り、git commit 時にコードが自動整形され、自動整形が走ったファイルをコミットできている事が分かる。

※なお、上記のGir hooksの設定はhuskyでも可能。

・参考:husky v5 で消耗している人には simple-git-hooks がお薦め
・参考:yarn v2 にまつわる誤解

まとめとして

今回は Prettier の推奨に則り、ESLint の静的解析と、Prettier のコード整形を分けて実行できるように設定してみた。上記のように設定する事でエディタ間の違いを吸収でき、開発者が複数いても確実にコード整形を自動で実行できるようになる。

※ちなみに VS Code であれば、以下のように設定する事で Extensions の Prettier をインストールすれば、ファイル保存時に Prettier のコード整形を自動で走らせる事もできる。

// settings.json
{
	"editor.defaultFormatter": "esbenp.prettier-vscode",
	"editor.formatOnSave": true,
	...
}


《この公式ブロガーの記事一覧》


執筆者プロフィール:Katayama Yuta
SaaS ERPパッケージベンダーにて開発を2年経験。 SHIFTでは、GUIテストの自動化やUnitテストの実装などテスト関係の案件に従事したり、DevOpsの一環でCICD導入支援をする案件にも従事。 昨年に開発部門へ異動し、再び開発エンジニアに。座学で読み物を読むより、色々手を動かして試したり学んだりするのが好きなタイプ。

お問合せはお気軽に
https://service.shiftinc.jp/contact/

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/