Skip to content

Instantly share code, notes, and snippets.

@x7ddf74479jn5
Last active April 16, 2023 08:53
Show Gist options
  • Save x7ddf74479jn5/1cf36b185950ce088130d60426cb4e2e to your computer and use it in GitHub Desktop.
Save x7ddf74479jn5/1cf36b185950ce088130d60426cb4e2e to your computer and use it in GitHub Desktop.
ESLint Flat Configメモ

ESLint Flat Configメモ

WIP:Dual Packagesの対応で詰まり中

設定例

環境

Name Version
VS Code 1.77.1
ESLint 8.38.0

Flat Configがサポートする環境:ESLintのversion 8.21以降(2023-04-13現在)

VS Code Pluginの設定

VS Codeを使っていてESLint拡張を有効化している場合、ファイル頭の"import/export"でParsing error: The keyword 'import' is reservedとエラーが出る。Flat Configはexperimentalな機能であるためVS Codeの設定画面から有効化する必要がある。ESLint › Experimental: Use Flat Configtrueに設定する。

説明

Flat Configではeslint.config.jsのファイル名で設定ファイルを記述していく。公式はESM形式だがCommnJS形式も可能。従来の設定ではESLintが実行時に暗黙的に依存解決していた部分を手動でひとつひとつ書いていく。まだexperimetalが外れていない(2023-04-14)。

用語

Configuration Objects

  • files: 設定オブジェクトが適用されるべきファイルを示すグロブパターンの配列です。指定されない場合、設定オブジェクトは、他の設定オブジェクトにマッチするすべてのファイルに適用されます。
  • ignores: 設定オブジェクトが適用されるべきでないファイルを示すグロブパターンの配列です。指定されない場合、設定オブジェクトはfilesにマッチするすべてのファイルに適用されます。
  • languageOptions: JavaScriptのリント設定に関する設定を含むオブジェクトです。
    • ecmaVersion: サポートするECMAScriptのバージョン。年(例:2022年)またはバージョン(例:5)を指定することができます。最新のバージョンをサポートする場合は、"latest "に設定します。(デフォルト:"latest")
    • sourceType: JavaScriptのソースコードの種類を指定します。指定できる値は、従来のスクリプトファイルの場合は「script」、ECMAScriptモジュール(ESM)の場合は「module」、CommonJSファイルの場合は「commonjs」です。(デフォルト: .jsと.mjsファイルには「module」、.cjsファイルには「commonjs」)
    • globals: リント中にグローバルスコープに追加されるべき追加オブジェクトを指定するオブジェクトです。
    • parser: parse() メソッドまたは parseForESLint() メソッドを含むオブジェクトです。(デフォルト: espree)
    • parserOptions: パーサーの parse() または parseForESLint() メソッドに直接渡される追加オプションを指定するオブジェクトである。使用可能なオプションはパーサに依存します。
  • linterOptions: リント処理に関連する設定を含むオブジェクトです。
    • noInlineConfig: インライン構成が許可されているかどうかを示すブール値。
    • reportUnusedDisableDirectives: 未使用の無効化ディレクティブを追跡して報告するかどうかを示すブール値です。
  • processor: preprocess()およびpostprocess()メソッドを含むオブジェクト、またはプラグイン内のプロセッサ名を示す文字列(例:"pluginName/processorName")のどちらか。
  • plugins: プラグイン名とプラグインオブジェクトの名前-値マッピングを含むオブジェクトです。filesが指定された場合、これらのプラグインは一致するファイルでのみ利用可能です。
  • rules: 設定されたルールを含むオブジェクト。filesまたはignoresが指定された場合、これらのルール設定は一致するファイルに対してのみ有効である。
  • settings: すべてのルールが利用可能であるべき情報の名前-値ペアを含むオブジェクト。

設定方法

現状Flat Configがexperimentalなため従来のeslintrc形式前提であることにより、内部実装を見て判断せざるをえない。各ESLint系パッケージの内部実装を見てextendspluginsrulesを探す。基本的にGitHubのindex.jsを見ていく。ルートになければ/src/libなどにある。

ルールは従来通りカスケードされるため後に書いた方のルール設定で上書きされる。

ルールセットの追加方法:

  • Pluginを読み込んでルールを個別追加する方法(Plugin系)
  • プリセットを読み込む方法(Config系)
  • プリセットが基本のルールを上書きする方法(Override系)

Config系にはeslint-config-*のすべてとeslint-plugin-*でプリセットを公開しているものが該当する。Config系は従来のeslintが依存解決を担う前提であるため互換性がない。FlatCompat()を使うことでFlat Config対応していない設定プリセットを取り込むことができる。

import { FlatCompat } from "@eslint/eslintrc";

const compat = new FlatCompat();

1. Config系(eslint-config-*

Next.jsなどの公式が出しているものの他に他人のプリセットを使いたい場合。

  1. FlatCompat()を使う。
  2. rulesで好みに拡張する。
import { FlatCompat }  from "@eslint/eslintrc"

const compat = new FlatCompat();

export default [{
  ...compat.extends("next/core-web-vitals"),
  rules: {
    "next/no-img-element": "off",
  }
}];

2. Plugin系(eslint-plugin-*

2.1 プリセットを使わず個別のルールをon/offしたい

  1. pluginsに登録する。
  2. rulesで好みに拡張する。
import react from "eslint-plugin-react"; 

export default [{
  files: ["**/*.tsx"],
  plugins: { react }, 
  rules: { 
    "react/prop-types": "off",
    "react/react-in-jsx-scope": "off",
    "react/display-name": "error"
  }
}]

2.2.1 プリセットを使う

index.jsconfigsプロパティがある場合。内部実装を見ていくとindex.js内にconfigs.{任意の名前}のような設定箇所が確認できる。これは従来の記法でextendsプロパティにplugin:と書いているやつ。プラグインが公開している推奨プリセットである(e.g. @typescript-eslint/recommended)。従来のESLintが依存解決を担う前提であるため互換性がない。

  1. FlatCompat()を使う。
  2. rulesで好みに拡張する。
import { FlatCompat }  from "@eslint/eslintrc"

const compat = new FlatCompat();

export default [{
  ...compat.extends("plugin:@typescript-eslint/recommended"),
   rules: {
    "@typescript-eslint/no-explicit-any": "off",
    "@typescript-eslint/no-var-requires": "off",
  }
}];

2.2.2 同一パッケージから複数のルールセットを読み込む

プラグイン重複登録の罠

import typescriptEslint from "@typescript-eslint/eslint-plugin";

export default [
  {
    plugins: {
      "@typescript-eslint": typescriptEslint,
    },
    rules: {
      ...typescriptEslint.configs["eslint-recommended"].rules,
      ...typescriptEslint.configs["recommended"].rules,
      ...typescriptEslint.configs["recommended-requiring-type-checking"].rules,
    },
  },
];

2.3 index.jsrulesのみ

  1. rulesにスプレッド演算子で展開していく。
import prettier from "eslint-config-prettier"

export default [{
  rules: {
    ...prettier.rules,
  },
}];

ESLint系パッケージの対応状況(2023-04-13)

@typescript-eslint/eslint-plugin

typescript-eslint/index.ts at main · typescript-eslint/typescript-eslint · GitHub

configs

  • all
  • base
  • recommended
  • eslint-recommended
  • recommended-requiring-type-checking
  • strict

eslint-plugin-jsx-a11y

eslint-plugin-jsx-a11y/index.js at main · jsx-eslint/eslint-plugin-jsx-a11y · GitHub

configs

  • recommended
  • strice

eslint-plugin-import

eslint-plugin-import/index.js at main · import-js/eslint-plugin-import · GitHub

configs

  • recommended
  • errors
  • warnings
  • stage-0(wip secret)
  • react
  • react-native
  • electron
  • typescript

eslint-plugin-sort-destructure-keys

eslint-plugin-sort-destructure-keys/index.js at master · mthadley/eslint-plugin-sort-destructure-keys · GitHub

rulesのみ

eslint-plugin-simple-import-sort

eslint-plugin-simple-import-sort/index.js at main · lydell/eslint-plugin-simple-import-sort · GitHub

rulesのみ。

eslint-plugin-react

eslint-plugin-react/index.js at master · jsx-eslint/eslint-plugin-react

configs

  • all
  • recommended
  • jsx-runtime

eslint-plugin-react-hooks

react/index.js at main · facebook/react · GitHub

configs

  • recommended

eslint-plugin-tailwind

eslint-plugin-tailwindcss/index.js at master · francoismassart/eslint-plugin-tailwindcss · GitHub

configs

  • recommended
import tailwind from "eslint-plugin-tailwind"; 

export default [{
  plugins: { tailwind }, 
  rules: { 
    ...tailwind.configs.recommended.rules
  },
  // メディアクエリごとにグループ化するため
  settings: { tailwindcss: { groupByResponsive: true } },
}]

eslint-plugin-node

eslint-plugin-node/index.js at master · mysticatea/eslint-plugin-node · GitHub

configs

  • recommended
  • recommended-module
  • recommended-script

@next/eslint-plugin-next

next.js/index.ts at canary · vercel/next.js · GitHub

eslint-config-nextが依存している。基本的にeslint-config-nextの方を使うので省略。下記eslint-config-nextの項を参照。

configs

  • recommended
  • core-web-vitals

eslint-config-next

next.js/index.js at canary · vercel/next.js · GitHub

// eslint-config-next/index.js

  extends: [
    'plugin:react/recommended',
    'plugin:react-hooks/recommended',
    'plugin:@next/next/recommended',
  ],
  plugins: ['import', 'react', 'jsx-a11y'],
// eslint-config-next/core-web-vigals.js

module.exports = {
  extends: [require.resolve('.'), 'plugin:@next/next/core-web-vitals'],
}

require.resolve('.')eslint-config-next自身、plugin:@next/next/core-web-vitals@next/eslint-plugin-nextconfigs.core-web-vitalsを参照している。

また、eslint-config-next@next/eslint-plugin-nextconfigs.recommendedを参照している。

extends

  • plugin:react/recommended
  • plugin:react-hooks/recommended
  • plugin:@next/next/recommended

plugins

  • import
  • react
  • jsx-a11y

eslint-config-prettier

prettier/eslint-config-prettier: Turns off all rules that are unnecessary or might conflict with Prettier.

rulesのみ。

参考

import configs from "@x7ddf74479jn5/eslint-config";
export default configs.react
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment