1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

WIP: ESLintのV9移行作業でFlatConfig含めて沼ったので振り返りメモ

1
Last updated at Posted at 2026-02-09

まだ未完成なので、今後内容が更新されていきます。

詰まった点

  • そもそもFlatConfigミリしら
  • 僕「cjs,mjs,js全部同じじゃないですか!?」「バカ、よく見ろ!」「これだから素人は」
    • commonJS, ESModuleを知らなかった
  • Configration Objectを知らない
  • ignoresだけのConfigration Objectはグローバル化される
  • 広い対象ファイルのfiles指定したbase.config.jsを継承したファイルで、対象ファイルを絞る場合はグローバルignoresが必要
  • V8からV9で追加/削除されたrecommendedルールがある

不明単語・疑問

  • Shareable Configとは何か?
  • Extendsの使い方と何を意味するのか?
  • parserOption

まとめ

  • ESLintと各プラグインの公式ドキュメントを読みましょう
    • これで終わってしまう

参考すべき資料

ESLintについて学習

参考資料

メモ

豊富なプラグイン

下記より抜粋
1.4 📚 ESLintのエコシステム|Next.js 実践入門 - ESLint 編

🧩 TypeScriptサポート系

⚛️ Reactサポート系(+JSX)

📦 モジュール構成・インポート整備系

🎨 コードフォーマット連携系(Prettierなど)

♿ アクセシビリティ(a11y)系

🧪 テストコード向けLint系

🔒 セキュリティ対策系

⚡ パフォーマンス・構文最適化系

他プラグイン

FlatConfigについてメモ

設定ファイルにできるファイル名

  • eslint.config.js

  • eslint.config.mjs

  • eslint.config.cjs

  • eslint.config.ts追加設定が必要

  • eslint.config.mts追加設定が必要)

  • eslint.config.cts追加設定が必要)

  • 「このファイルはプロジェクトのルートディレクトリに配置してください」と書かれているが必須ではない。

    • 今のプロジェクトだとモノレポなので、eslint設定用のパッケージを作成してベース設定ファイルを定義して他パッケージにそれぞれカスタムの設定ファイルを置いている。
      • turborepoでのESLintで少し触れます。

ファイル内容

eslint.config.js
// eslint.config.js
import { defineConfig } from "eslint/config";

export default defineConfig([
  {
    rules: {
      semi: "error",
      "prefer-const": "error",
    },
  },
]);

このファイルでエクスポートされるオブジェクトをConfigObjectと呼ばれている。

defineConfig

defineConfigは設定をラップするただのヘルパー関数なので必須ではない。

ただ、入力補完できたり型チェックや設定ミスを防げるので入れておくのが吉。

eslint.config.js
export default [{
  {
    rules: {
      semi: "error",
      "prefer-const": "error",
    },
  },
}];

注意点

eslint.config.jsと同パスのpackage.json"type":"module"指定しないとCommonJS形式になることに注意

require()でインポートすることになって若干めんどい

// package/hoge/eslint.config.js
const { defineConfig } = require("eslint/config");

module.exports = defineConfig([
  {
    rules: {
      semi: "error",
      "prefer-const": "error",
    },
  },
]);
  • 基本的にはeslint.config.jsでESMとして定義して使うのが無難そう。
    • 理由としては、ESLint使っている現場でだいたいTypeScriptを使っているので書き方を統一できるため

ConfigObject(設定オブジェクト)について

  • name: configObjectを命名できる。また、エラー発生した際にどの設定でエラーしたか分かりやすくなる。
  • basePath: ルールを適用するパスを設定します。(相対パス/絶対パスのどちらか)
  • files: ルールを適用するファイルを設定できる。(globパターンで指定する。 ex.**/*.ts)
  • ignores: ルール適用対象外ファイルを設定する。(これもglobパターン形式)
  • extends: 他の人が作った設定一式を丸ごと継承(インポート)する
  • languageOptions: リント時のJS設定に関連する設定群
    • ecmaVersion: ECMAScriptのバージョンを指定する。年号(2025),Version番号(5),latest(最新)など指定できる
    • sourceType: JSソースコード種類を指定する。(ECMAScriptModule,CommonJS,スクリプト)
      • .cjs: commonJS
      • .mjs: module
      • スクリプト: script
    • globals: グローバル変数を定義して、ESLintがコード内で使用されているグローバル変数を認識できるようにする
    • parser: パーサーを指定する。(ex.tsParserなど)
    • parserOptions: パーサーの動作を設定。言語の機能や環境を指定できる。
  • linterOptions :リント処理の設定
    • noInlineConfig :インライン設定を無効/有効を設定
    • reportUnusedDisableDirectives: 未使用の無効化ディレクティブの報告設定
    • reportUnusedInlineConfigs: 未使用のインライン設定の報告設定
  • processor
  • plugins: 新しいルールや機能を提供するパッケージを読み込む
  • rules: 個別のルールを有効/無効/調整
  • settings: プラグイン間で共有する設定情報

plugins, extends, rules, settingsの違いがよくわからない自分...

  • plugins: 新しいルールを提供するパッケージを読み込む(読み込んだだけで
    はルールは有効にならない)
  • extends: 他の人が作った設定一式を丸ごと継承(プラグイン読み込み+ルー
    ル設定を一括で行う)
  • rules: 個別のルールを有効化・無効化・調整する(最優先で適用される)
  • settings: プラグイン間で共有する設定情報(Reactのバージョン設定など)

簡単な設定例(ESM)

// eslint.config.js(ESM)
import { defineConfig } from "eslint/config";
import tseslint from "typescript-eslint";
import globals from "globals";

export default defineConfig([
  { name: "ignore", ignores: ["dist/**", "node_modules/**"] },

  {
    name: "base",
    files: ["**/*.js"],
    languageOptions: {
      ecmaVersion: "latest",
      sourceType: "module",
      globals: globals.node,
    },
    rules: { semi: "error", "prefer-const": "error" },
  },

  {
    name: "ts",
    files: ["**/*.ts"],
    languageOptions: {
      parser: tseslint.parser,
      parserOptions: { projectService: true },
    },
    plugins: { "@typescript-eslint": tseslint.plugin },
    rules: { "@typescript-eslint/no-unused-vars": "warn" },
  },

  {
    name: "linter",
    linterOptions: { reportUnusedDisableDirectives: "warn" },
    settings: { sharedValue: true },
  },
]);
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?