[追記:] TypeScriptでESLintを使う方法も書きました
TSLintではなくESLintを使いたい方はこちらもあとで読んでみてください。
なお
- JS with ESLint
- TS with TSLint
この構成をお求めの方は当記事(下記)です。
Prettier導入するにあたって色々絡み合うものがあるので調べたりしたことをまとめておく。
基本的にリントとフォーマッタのどちらか片方しか使わないという場面は、リリースを意識したプロジェクトではあまりないと思うので、実質この組み合わせは必須のようになってくる気がしている。
それで、Prettierとはなんぞや…JSのコードフォーマッタで、、というPrettierの概要についてはググればめっちゃ出てくるので省略。
この記事は導入したいけどなにをどうすればいいんやという人向け。
とりあえずESLint+Prettierについて書いて理解してもらったあとでTypeScripter向けにTSLint+Prettierのことも書いてあります。ちなみに導入についての話なのでESLintやPrettierのルールの解説はない。
そもそもESLintとPrettierどう違うんやみたいなのは公式にこういうページがある。
CAVEAT
この記事を参考にすべき対象者
この記事はプロジェクトフォルダ内でESLintとPrettierを併用しつつ、コミット時にも再確認してgitにESLintルールに従っていないコードやPrettierによる未整形のコードが紛れ込まないようにしたい人向けです。
つまり
- プロジェクトフォルダがある
- はい
- プロジェクトに存在するコードの秩序を保ちたい
- はい
- ESLintでコードのルールチェックをしたい
- はい
- Prettierも使って整形済みのキレイなコードを保ちたい
- はい
- Gitに秩序が保たれていないコードが紛れ込むのを阻止したい
- はい
こういう欲求がある人向けです。
一番まとまっている導入解説
ESLint導入環境にprettierを追加して運用する - Kenta Katoh's Blog
この方のブログが一番簡潔でわかりやすいのでまず読むとわかってくる。
なので読むとわかる。…読んで下さいで終わると雑すぎるので、以下から導入解説。
導入しましょう
導入するにあたってなんか色々プラグインがあってどれを入れればいいのか問題が発生すると思う。
上記ブログにも書いてあるけれど、Prettierの処理の取り扱いには2種類ある。
.eslintrc
にPrettierのルールを定義 → ESLintの処理時にPrettierのルールもやってもらうPrettierでフォーマット → フォーマット済みコードを
eslint --fix
に繋いで渡す → ESLintにはESLintの処理してもらう
ESlint+Prettierの導入は上記2つのどっちかのやりかたでできる。
【1の特徴】
- 既存ESLint環境がある場合に導入しやすい
.eslintrc
にPrettierの設定をできて一元管理感がある- Prettier使うことが明示されるのでわかりやすくてよい
eslint --fix
したタイミングでPrettierも実行される- どうせPrettierするならESLintもするでしょう?という人によさげ
【2の特徴】
- 処理を担うのは
prettier-eslint
もしくはprettier-eslint-cli
というプラグイン- 前者はJSファイルにimportして使うライブラリタイプで、後者はcliコマンドでやりたい場合
prettier-eslint
を使うとPrettierしてからeslint --fix
してくれる- PrettierとESLintの処理をそれぞれ分けておける
- Prettierのオプションは
.prettierrc
で管理するか、エディタのIntegrationプラグイン上で設定する問題がある
どっちでもいいけど自分は1.の手法をとっている。というのも最初に書いたようにESLintとPrettierは併用が実質必須みたいになりつつある(ESLintのみだけならまだしもPrettierのみという場面はなさそう)。なのでESLintの設定と一緒にPrettierの設定も書かれていたほうが1枚に設定がまとまっていてわかりやすいからそうしている。
ちなみに2のやり方は実際に使ってないので当記事では省略します。
1.のやりかた
というわけで1.のやりかたでの導入。
ESLint + Prettierをまず入れる
yarn add -D eslint prettier
yarnで書いているけれど別にnpmでもよい。お好きなパッケージツールで。
これでESLintとPrettier本体が入った。
次にESLintのPrettier用プラグインとコンフィグを入れる
GitHub - prettier/eslint-plugin-prettier: ESLint plugin for Prettier formatting
eslint-plugin-prettier
- ESLintのルールとしてPrettierを読み込んで個々に処理するやつ
eslint-config-prettier
- ESLintとPrettierの処理で重複する部分を無効化してくれるやつ
yarn add -D eslint-plugin-prettier eslint-config-prettier
とりあえず必要なものは入ったのであとは.eslintrc
に設定を書いていく。
.eslintrc
以下.eslintrc.json
の例
eslint-plugin-prettier
のconfig
{ "plugins": [ "prettier" ], "rules": { "prettier/prettier": "error" } }
次にeslint-config-prettier
のconfig
{ "extends": [ "prettier" ] }
合わせるとこう
{ "extends": ["prettier"], "plugins": ["prettier"], "rules": { "prettier/prettier": "error" } }
最小限できた。
実際にはこれに加えてESlintのRuleがめっちゃ書かれるか、AirbnbないしはxoないしはGoogleないしはStandardあたりのなにかしらのルール郡をextendsで利用することになる。
以下は僕が実際に使ったりするESLintの例。
GitHub - standard/eslint-config-standard: ESLint Config for JavaScript Standard Style
JavaScript Standardをベースにしている.eslintrc.json
。
{ "extends": ["standard", "prettier"], "env": { "browser": true }, "plugins": ["prettier"], "rules": { "prettier/prettier": [ "error", { "singleQuote": true, "semi": false } ], "yoda": 0, "no-unused-vars": 1 }, "globals": { "$": false } }
standard使う場合は以下も必要なのでやっている、がここでは本筋ではないので閑話休題ということで…
yarn add -D eslint-config-standard eslint-plugin-standard eslint-plugin-promise eslint-plugin-import eslint-plugin-node
エディタ側の設定
ここまででPrettierを使う準備はできた。ので、エディタの設定をする。
VS Codeでの例で書く。
ESLintのプラグインを入れる。
⌘+,
するかVS Codeの設定を開いて
"eslint.autoFixOnSave": true
すると保存時にeslint --fix
されるのでPrettierもされる、という流れになる。
これで無事ESLint+Prettierが使えるようになった。
Prettierのプラグインはエディタに入れなくてもいいんですか?
各エディタにはPrettierのプラグインもある。これは必要なのかどうかという悩みが出る。
端的にいうとこれまで解説してきたやりかただけをやるのであれば必要ないということになる。
これまでの解説はESLintとPrettierを併用することを前提としたプロジェクト単位での話で、『2つを併用するとルール面でコンフリクトが起こるのでよしなにしたい』というのが根底にあるからいろいろプラグイン入れたりコンフィグ書いたりしている。
そもそもPrettierだけを単体で使うだけであれば、エディタにプラグインを入れてしまえばOKという事実がある。逆にいえば、プロジェクト単位ではないような…例えばgitにも上げないような実験的なJSを書くときもPrettierを使って書きたいのなら、エディタのPrettierプラグインを入れる必要がある。
Prettierプラグインの設定にもESLintのプラグイン同様に"onSave"のような設定があって、保存時にPrettierが走るようにできる。でもこれを設定しておくと、これまで解説してきたようなeslint --fix
でPrettierも走るようなプロジェクトを触るときに2回Prettierが走るので、注意したほうがいいという問題はある。なので自分はPrettierのプラグインを使う場面では手動で実行させている。
エディタ依存になるのでgit hookでPre-commit時にPrettierしましょう
自分は上述のエディタ連携をしてファイル保存時に逐一PrettierとESLintが走り、エラーが出たら都度直すほうが好きなのでそういう使いかたをしている。でもOSSとか複数人で共有するプロジェクトの場合、全員がエディタプラグイン入れて連携させる必要が出てきてこれではよくない。誰かがエディタ連携しないままgitにプッシュするとESLint&Prettierの検閲がされていないコードがgitに紛れ込んでしまう。
そういうわけでgit commit
すると自動でeslint --fix
が走るように設定しておくと間違いがなくなって便利。
公式に解説があってやりかたは複数あるけどポピュラーっぽいHuskyとLint-stagedを使う方法で僕はやっている。
まずhusky
とlint-staged
を入れる。
yarn add -D lint-staged husky
package.json
に以下を追加
{ "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.{js,jsx}": [ "eslint --fix", "git add" ] } }
これでgit commit
時にESLintのFixが走るのでgitコミットされるコードは確実にlint&format済みのコードということになって秩序が生まれる。
TypeScriptでPrettierしたい
上記まででJS環境=ESLint+Prettierを併用できるようになった。TS環境=TSLint+Prettierではどうすればという解説。
流れは同じなので雑に書きます。
まず必要なライブラリを入れる
yarn add -D tslint prettier tslint-config-prettier tslint-plugin-prettier
- GitHub - prettier/tslint-config-prettier: Use tslint with prettier without any conflict
- eslint-config-prettier相当
- GitHub - prettier/tslint-plugin-prettier: Runs Prettier as a TSLint rule and reports differences as individual TSLint issues
- eslint-plugin-prettier相当
tslint.json
を書く
{ "rulesDirectory": ["tslint-plugin-prettier"], "extends": ["tslint-config-standard", "tslint-config-prettier"], "rules": { "prettier": [ true, { "singleQuote": true, "semi": false } ] } }
こういう感じ。
エディタのTSLintプラグイン
Pre-commit
ESLintのときと同じ。husky
とlint-staged
を入れる。
{ "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.{ts,tsx}": [ "tslint --fix", "git add" ] } }
lint-staged
を.ts対象にする
基本的にESLintとやりかたは同じで、tslint.jsonの書き方が若干ESLintと異なるくらいだと思う。
ちなみに
これは小ネタではあるけど、ESLintは.eslintrc
を探すときルートディレクトリまでずっと遡って探索する。ので、仮にプロジェクトに.eslintrc
がなければユーザーのローカルルートディレクトリまで遡る。
ルートにdotfilesを置く風潮なので、自前の.eslintrc
をルートディレクトリにおいておけば、例えば雑にエディタでJSを書くときにはルートにある自前の.eslintrc
が参照される。
エディタのプラグインに.eslintrcの場所を指定するオプションがあったりするけど、基本的に特殊な階層において管理していないのであれば、ああいう設定は不要だったりする。
長くなったけどESLint+Prettierを導入するにはこういう感じです。
.eslintrc
でPrettierも管理して実行はeslint --fix
駆動ということが理解できればそんなに難しくないけど付随する設定やプラグインが多すぎる。1個にまとめて欲しい気もする。