メモ代わりに関係ない情報も色々含めた。
これまでのあらすじ
ESLint is 何
JSのLinter。めっちゃカスタマイズできる。
eslint --fix
コマンドでフォーマットもできる。
Prettier is 何
JSのフォーマッター。eslint --fix
よりも強いらしい。
具体例で言うと、「1行80字超えのコードを適切に改行してくれる」らしい。
やたらこの例を推してくる。他の例を知りたい。
Prettier only ダメ is なぜ
フォーマットしかできない
Linterのルールには2種類ある。
- フォーマットに関するルール
- コードの品質に関するルール
「後者はLinterの仕事。Prettier、ソウイウノ、ヤラナイ。」的なことが公式で案内されている。
カスタマイズ性に乏しい
ESLintほど充実していない。
よりカスタマイズできる版を提供しようっていうフォークプロジェクトがあるぐらい。
応援したい。でも開発止まってるっぽい。
Why don't you ESLintとPrettierを併用?
Yes, I am.
併用 is どうやる
prettierをかましてからeslint --fix
をかます。
Code ➡️ prettier ➡️ eslint --fix ➡️ Formatted Code ✨
prettier/prettier-eslint
公式リポジトリにそういうプロジェクトがあるぐらいなので、アリっぽい。
個人的にはそれで良いのか感がすごい。
Prettier流のフォーマットがどれだけ上書きされてるのか知りたい。
やはりPrettierの優位な点をリストアップした資料とかが欲しい。
「80字超え対処」しか強みがないならこれで良いと思う。
ESlintをカスタマイズしてPrettierと連携させる。
prettier/eslint-config-prettier
prettier/eslint-plugin-prettier
この辺を組み込む。すると、eslint --fix
をした時にprettier準拠でフォーマットがされることになる。
以下、この辺の仕組みの解説。
※ 2020/12/27 追記
(コメントにて @masato_makino さんから指摘頂いた内容。)
prettierリポジトリにあるドキュメントが2020年6月頃に更新され、「eslint-plugin-prettierは非推奨。まあ特定の状況では便利かもね。」みたいなことが書かれるようになった。
以下、このドキュメントから読み取ったことを雑に羅列。
- リンターを使わなくても
prettier --check .
があるよ。 - 昔はprettier用のエディタプラグインがなくて、リンター向けのプラグインを使うしかなかったから、しょうがなくリンター経由でprettierしてたかもしれないけど、今時はどのエディタもprettier用のプラグインがあるからその必要はないよ。
- リンター経由だとエディタ上で赤線出まくったりしてだるいぞ。
- 直接prettierした方が速いぞ。
- 間接的なレイヤーを1個挟むことによって、何か余計なバグが生まれるリスクがあるぞ。
- prettierのフォーマットに気に入らない部分がある?じゃあprettier-eslintでprettier後のコードを
eslint --fix
して帳尻合わせてくれ。まあ重いけどね。
ということなので、eslint-plugin-prettierを使うより直接prettierコマンドを叩く方が推奨らしい。なお、eslint-config-prettierの使用は問題ない。
以下、その辺を考慮しながら必要な情報だけ取捨選択してもらいたい。
(追記終)
本題
ESLintの設定について
概要
ソース内コメントや設定ファイルによって色々カスタマイズできる。
設定ファイルは、package.json
内にeslintConfig
フィールドを設けて記述するパターンと、.eslintrc.{js|json|yaml}
ファイルを作るパターンがある。
設定の優先順位
高い順に
- コメント
- CLIコマンドのオプション
- 設定ファイル
-
.eslintrc.*
を置いたフォルダの子フォルダに更に.eslintrc.*
を置いたりできる。- チェックするjsファイルについて、近い階層に置いてある
.eslintrc.*
の設定ほど優先して採用される。 -
.eslintrc.*
内でroot: true
を指定すると、それより親フォルダの.eslintc.*
は無視される。
- チェックするjsファイルについて、近い階層に置いてある
-
.eslintrc.*
とeslintConfig
を記載したpackage.json
の両方が同じ階層にある場合、eslintConfig
は無視される。
-
上記のどれか1つしか採用されないわけではなく全部採用される。競合する設定について優先順位が考慮されるイメージ。
オブジェクト指向的にいえば、設定をどんどんオーバーライドしていってる感じ。
また、ホームディレクトリに.eslintrc.*
があるとフォールバックとして働く。
上記の3つが全部無かった時のみここの設定が反映される。
設定できることの一例:ルールのON/OFF
module.exports = {
"rules": {
// ==を使おうが===を使おうが気にしない。
"eqeqeq": "off",
// if文などで{}を略したらwarning。
"curly": "warn",
// ダブルクォートを使う。シングルクォートを使ってたらLinterエラー。
"quotes": ["error", "double"],
// セミコロンは必須。無かったらLinterエラー。
"semi": ["error", "always"]
}
}
他には、環境(ECMAいくつか、nodeかbrowserか、jQuery使ってるか、etc...)、グローバル変数の設定など。
設定の共有
eslint-config-*
という名前でnpmモジュールとして設定を共有できる。
例えば、eslint-config-standard
は以下の記述で取り込むことができる。
{
"extends": "standard"
}
ただし、記述するだけでなくnpmで自分で落としてこないといけない。
ESLintを入れた場所がプロジェクトローカルならプロジェクトローカルに、グローバルならグローバルに。同じレベルに落とさないと使えない。
複数の設定を取り込むこともできる。
{
"extends": [
"eslint:recommended",
"standard"
]
}
後のやつが前の設定をどんどんオーバーライドしていく。
取り込んだ後、更に自分でrules
とか設定しだすのもオーバーライドになる。
設定のプラグイン
eslint-plugin-*
という名前でnpmモジュールとしてプラグインを作成できる。
ルールを増やしたりできる。共有設定を含めることもできる。
例えば、eslint-plugin-react
は以下の記述で取り込むことができる。
{
"plugins": ["react"]
}
プラグイン内のルールは以下のように指定する。
{
"plugins": ["react"],
"rules": {
"react/no-set-state": "error"
}
}
プラグイン内の共有設定は以下のように取り込む。
{
"plugins": ["react"],
"extends": ["plugin:react/recommended"]
}
Prettier連携
方針
eslint --fix
の仕様についてはちゃんと調べていないが、おそらく「ルール」の中には「どう直すか」も含まれている。
ということは、ESLintの組み込みルールを全部無効にし、Prettierのプラグインルールに差し替えまくればいいことになる。
上の方で、ルールには2種類あると書いた。
- フォーマットに関するルール
- コードの品質に関するルール
Prettierの担当範囲は前者である。
なので、前者に関するESLintの組み込みルールを全部オフにする。
eslint-config-prettier
の使い方
共有設定prettier
を取り込むことで、Prettierと競合しそうなESLintの組み込みルールを全部OFFにしてくれる。
react
プラグインの分をOFFにする共有設定prettier/react
等、細かい追加分もある。
eslint-plugin-prettier
の使い方
これを取り込むことで、Prettierのルールが代わりに追加される。されるのだが...。
なんと、
{
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error"
}
}
prettier
というルール1つしか追加されない。
Prettierが扱う全ルールが、この1つにまとめられている。
つまり、ルール毎にON/OFFを細かく設定できない。
全部offか、全部warningか、全部errorかしかない。
しかし、全くカスタマイズが効かないというわけではない。
例えば、ESLint組み込みのindent
ルールは、ルールのON/OFFだけでなくインデント幅のルールも設定できる。
module.exports = {
"rules": {
// インデント幅が2でなければLinterエラー。
"indent": ["error", 2]
}
}
同じノリで、prettier
ルールもオブジェクトを使って色々ルールを設定できる。
module.exports = {
"plugins": ["prettier"],
"rules": {
// シングルクォートを使う。セミコロンは無し。
"prettier/prettier": ["error", {"singleQuote": true, "semi": false}]
}
}
無理やり感がすごい。
ちなみに.prettierrc
ってファイルで設定する方法もあるらしい。
なお、このプラグインには共有設定recommended
も含まれている。
{
"extends": ["plugin:prettier/recommended"]
}
上記により、下記と同じ効果が得られる。
{
"extends": ["prettier"],
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error"
}
}
逆にいうとそれだけ。
手順まとめ
npm install --save-dev eslint
npm install --save-dev eslint-config-prettier
npm install --save-dev eslint-plugin-prettier
npm install --save-dev prettier
Prettier本体は雰囲気で入れてるけど、本当に必要なのかは未検証。
module.exports = {
"extends": ["prettier"],
"plugins": ["prettier"],
"rules": {
"prettier/prettier": [
"error",
{
// 各種設定
}
]
}
}
他に取り込みたい共有設定があれば、prettier
より前にextendする。(prettier
でルールOFFにする方が優先順位が高いので。)
愚痴
JavaScript Standard Styleに合わせたいのだが、PrettierにspaceBeforeFunctionParen
オプション(関数名と引数名の間にスペースを空ける。ex. function name (arg) { ... }
)が無いため合わせられない。
- フォークプロジェクト頑張ってほしい。
- というか普通にPrettierがカスタマイズ性上げてほしい。
- というかStandard Styleはこの仕様だけマイナーなのでやめてほしい。
- というかセミコロン無しのStyleでもっと良いの出てきてほしい。