eslintのpluginsとextendsの違いを理解する
本記事は「つながる勉強会 Advent Calendar 2022」の 20日目の記事です。
19日目はあっこさんの以下の記事でした。
結構色んな方が記事書いてるのでよかったら見てみてください。
*普段のブログは常体で書いてるのですが、Advent Calendarということもあり、今回は敬体で書くことにします。
さて、数ヶ月前にeslintのflat configが発表されました。
これは設定ファイルの書き方に関するもので、これまでの書き方と色々と違うところがありますが、簡単に言うとよりシンプルな記述で設定を書けることを意図したものらしいです。
詳細は以下の記事がとても参考になりました。
確かにeslintの設定ファイルって複雑になりがちでかなり読みにくいです。
結局どのpluginが読み込まれてるのかわかりにくいし、特定のファイルのみに適用するルールの場合は全体でonにして、overridesで一部offに上書きという仕様はあまり直感的ではないように思います。
そういったモヤモヤしたのがflat config使うとスッキリ解決するとのこと。
というわけで従来していた設定をflat configで書き直そう!
と思ったんですが、そのためにはそもそも従来通りの設定をちゃんと理解する必要があるというわけで、この記事ではこれまで雰囲気で書いていたeslintの設定の意味をちゃんと調べて理解できたことをメモしていくことにします。
特にpluginsとextendsの挙動の違いが理解できてなかったのでその内容が中心になります。
そして次回の記事で実際にflat configを使って書くと記述がどう変わるのかを見ていきます。
本記事では主に以下のことを書いています。
- プロパティにある
extends
とplugins
の挙動の違い - eslint-config-xxxとeslint-plugin-xxxの違い
十分調べて書いたつもりですが、間違っていたら教えてください。
pluginsとは
おそらくplugins
の方から説明する方がわかりやすい気がしたのでplugins
から。
pluginとは、ESLintに様々な拡張機能を追加するためのnpmパッケージです。
新しいルールの追加やshareable configsのexportができるようになります。
shareable configsの話はextendsの際に説明するので一旦後回しにして、最も基本的な?新しいルールの追加機能を見ていきます。
例としてimport
に関するあれこれのルールを追加できるeslint-plugin-import
というパッケージをインストールします。
そして以下のようにplugins
にimport
を書いて、rules
の中に該当ルールを記載すれば適用されます。
plugins
の中に書いたimport
はeslint-plugin-import
を使用することを指しています。
このパッケージによらず、eslint-plugin-
は省略して書くことができる仕様になっているようです。
この時、pluginはあくまでルールセットを拡張するだけなので、実際にどのルールを適用させるかはrulesの中に記載する必要があります。
(*後に記載するshareable configsを使わない場合は)
extendsとは
shareable configsに書かれた設定を継承するためのプロパティです。
shareable configsとは?
先ほどもplugins
で出てきたのでここでちゃんと説明しておきます。
eslintの設定は様々なプロジェクトで何度も同じような設定を書いて使うことが多いです。
そのため、そういった一連の設定をnpmパッケージで管理しておいて読み込んで使えると簡単に共有できて良さそうに思えます。
これを実現したのがshareable configsであり、簡単に言えば色んな設定が既に書かれたeslintの設定ファイルと言って差し支えないのではないでしょうか。
先述したplugins
だけでなくrules
やenv
など、eslintの設定ファイルに記載する内容があらかじめ定義されています。
つまり、該当のnpmパッケージをinstallして、extends
で読み込めば適用されるようになっています。
読み込み方はpluginの時と似ていて、eslint-config-foo
というnpm packageならばeslint-config-
の部分は省略できます。
つまり、eslint-config-prettier
をinstallして、"extends": ["prettier"]
と書けばeslint-config-prettier
の内容が適用されます。
参考までにeslint-config-prettier
の中身を見てみると以下のようになっていました。
様々なルールが設定されているのが見てとれます。
そのため、plugins
とは違って、extends
で読み込めばrules
の中を自分で設定しなくても適用されるルールが存在し得ます。
extends
の中で被った設定に関しては後の方が優先して適用される仕様になっています。
prettierとeslintを同時に使う際に競合しないようにするには、現在上記の方法が推奨になっていますが一番最後に書くのも納得です。
pluginによるshareable configsのexport
plugins
内の記述で「shareable configsのexportができる」と記載しました。
例としてeslint-plugin-react
の中身を見てみると、以下のようなconfigs
というプロパティが見つかります。
ここにはrecommended
とall
とjsx-runtime
が存在していて、それぞれに必要なルールをはじめとしてplugins
とparserOptions
が設定されています。
そう、これはまるでshareable configsであり、eslint-plugin-foo
というパッケージの中でconfigs
にshareable configsを設定してexportすることができるということです。
これはextends
で以下のように記載すれば適用されます。
ここでも例によってplugin名のところはeslint-plugin-
を省略できます。
従って以下の設定はeslint-plugin-react
のパッケージの中にあるconfigs
のrecommended
部分を適用するという意味になります。
pluginsに明記しなくてもルールが適用されるケース
実はextends
に以下のように設定した場合はplugins: ["react"]
を記載しなくても適用されます。
その理由は、このrecommended
の設定の中でplugins: ['react']
が既に記載されているためです。
上書きしたり追加したりしたいルールがあった場合はそのままrules
の中に書けば適用されます。
plugins
に書いてないのにルールが適用されるというのはこのようなextends
した中で既にplugins
が記載されているというケースのはずです。
ただし、実際に使うplugin
のnpmパッケージ自体はインストールしておく必要があります。
まとめ
esling-plugin-foo
は様々な拡張機能を追加するためのnpmパッケージであり、以下のことができるようになります。
- 新しいルールの追加 (
plugins
に記載) - shareable configsのexport (
extends
にplugin: [plugin名]/[config名]
の形で記載)
eslint-config-foo
は再利用可能な様々な設定を含んだnpmパッケージであり、extends
に書くことでルールをはじめとした諸々の設定が適用されます。
個人的にはeslint-plugin-
が省略されるみたいな仕様は逆に依存関係がわかりにくくなってかなり微妙だなと思ってます(実際今回ちゃんと調べるまで理解できてなかったです)
ただしそれもflat configを使うと依存関係が明示的になっていてよかったので次の記事で紹介します