📝

ESLint v9以降(flat config形式)でeslint-plugin-reactを設定する

に公開

経緯

最近、Reactサービスから離れていたので個人学習を兼ねてReactを構築中に
v9以降でのlint設定(React関連)を行おうとし躓いたので同じ様な事象に遭われた方に
解決の共有またはヒントになれば幸いです。

躓いた理由

  1. ESLint設定ファイル形式の変更
    • v9.0.0以降はFlatConfig形式がデフォルトになった
    • 従来の.eslintrc.{js|json|yml}形式は動作しない
      • v8までは従来形式がデフォルトでFlatConfigは実験的導入の扱い
  2. 対応手順が散見しており何が正解かが判断しづらかった
    • FlatConfig対応の形式がパッケージによって異なる
      • 対応しているが記法がパッケージ構成に依存するパターン
      • FlatConfig対応が出来ていないパッケージのパターン
        • ESLint互換性ユーティリティ(@eslint/compat)を使用した回避対応が多い
        • AIを使用したが上述の情報ばかり食ってしまいv9以降の対応が見つかりづらい

(勉強不足なだけですぐAIだけに頼ってはダメですね...)

設定内容

最小構成の設定は以下で動作

eslint.config.{js|mjs}

import { defineConfig, globalIgnores } from "eslint/config";
import react from "eslint-plugin-react";

export default defineConfig([
  globalIgnores(["dist"]),
  {
    files: ["**/*.{ts,tsx}"],
    extends: [react.configs.flat.recommended],
    plugins: {
      react,
    },
  },
]);

実行結果(正常にlintが走った):

npx eslint . --fix

capture

plugins

https://eslint.org/docs/latest/use/configure/migration-guide#importing-plugins-and-custom-parsers

  • pluginsの記述はplugins: { key: value }形式

以下の様に書いてみた

import react from "eslint-plugin-react";

// 略
plugins: {
  react: react
}

が結果はエラー

Oops! Something went wrong! :(

ESLint: 9.36.0


A config object has a "plugins" key defined as an array of strings. It looks something like this:

    {
        "plugins": ["react"]
    }

Flat config requires "plugins" to be an object, like this:

    {
        plugins: {
            react: pluginObject
        }
    }

Please see the following page for information on how to convert your config object into the correct format: https://eslint.org/docs/latest/use/configure/migration-guide#importing-plugins-and-custom-parsers

If you're using a shareable config that you cannot rewrite in flat config format, then use the compatibility utility: https://eslint.org/docs/latest/use/configure/migration-guide#using-eslintrc-configs-in-flat-config
  • エラー出力はkey: valueを要求(対応しているのに)
  • 他パターンも試したがエラーになる
    • "packageName": package"の記法
    • key: fixupPluginRules(package)の記法(ESLint互換性ユーティリティ使用)
      import { fixupPluginRules } from "@eslint/compat";
      import react from "eslint-plugin-react";
      
      // 略
      plugins: {
        react: fixupPluginRules(react), // 互換性パッケージ使用の形式だが動作せず
      
      // v9以降は下記の記法は動作する認識だがeslint-plugin-reactは何故か動作しなかった
        react: react,
        "react": react,
      },
      
  • 他に設定したパッケージは先程動作しない記法でも正常に動作する
    // 下記の記法で動作している
    plugins: {
      import: importPlugin,
      "unused-imports": unusedImports,
      ...,
    },
    

下記リンクのREADMEのplugin項目のコードブロック内を参考に記述したら動作した
https://www.npmjs.com/package/eslint-plugin-react

plugins: {
  react
}

詳しい説明が見当たらず推測ですが以下の認識

“pluginsはオブジェクトとして指定する”という説明通りkeyを省略した
オブジェクトショートハンドと解釈し動作するのでは?

extends

https://www.npmjs.com/package/eslint-plugin-react
READMEのFlat Configs項目を参考に記述した

extends: [
  react.configs.flat.recommended
]

ただ他のプラグインは大体以下の形式で利用可能

extends: [
  packageName.configs.recommended
]

この結果からパッケージ毎に違いがあるからESLintを見るよりパッケージ側を見た方が
答えを見つけるのは早いかもしれないです。

実際にやってみて

  • 記述パターンは決まっているものの、パッケージごとに微妙に記法が異なるのはやや不便
  • エラー出力のリンクを見ても、その対応では解決しないケースがある
  • 結果的にパッケージ README を確認する必要があり、情報が散乱していてコストが高い

一方で、flat config に対応しているプラグインはシンプルに使えたのも事実。
今後は統一されていくことに期待です。

https://eslint.org/blog/2022/08/new-config-system-part-2/

長くなりましたが少しでも見て下さった方の躓きが解消されればと思います。

Discussion