コドモン Product Team Blog

株式会社コドモンの開発チームで運営しているブログです。エンジニアやPdMメンバーが、プロダクトや技術やチームについて発信します!

ESLintの設定をeslintrcからFlat Configへ移行しました

こんにちは。コドモンの羽馬です。

この記事では、コドモンの保護者向けアプリケーション開発で使用しているESLintの設定を新しいFlat Config形式へ移行した取り組みをご紹介します。

ESLintとFlat Configについて

ESLintは、JavaScriptやTypeScriptのコード品質を保つための静的解析ツールです。コーディングスタイルの統一、潜在的なバグの検出、ベストプラクティスの遵守などを自動的にチェックし、開発チームのコード品質を向上させます。

eslint.org

Flat Configは、ESLint v8.21.0で実験的機能として導入され、v8.57.0で安定版となった新しい設定形式です。v9.0.0では従来の.eslintrc.*ファイルによる設定(eslintrc形式)が非推奨となり、Flat Configがデフォルトの設定方法となりました。

eslint.org

移行の背景

Flat Config形式への移行を決めた理由は、将来の互換性への対応です。

公式アナウンスによると、従来のeslintrc形式はESLint v10で削除される予定となっています。この変更に対応するため、Flat Config形式への移行を決断しました。

移行手順

1. eslint-migrate-config ツールの実行

最初に、ESLint公式が提供する移行ツールを使用しました。このツールは既存の設定ファイルを読み込み、Flat Config形式に自動変換します。

www.npmjs.com

$ npx @eslint/migrate-config .eslintrc.js

実行すると、新しいeslint.config.jsファイルが生成され、必要なパッケージもリストアップされます。

ただし、JavaScript形式の設定ファイル(.eslintrc.js等)を使用している場合、注意が必要です。移行ツールは設定の最終的な結果のみを変換するため、条件分岐や関数などの動的な処理が失われます。環境に応じて設定を切り替えるような複雑な処理がある場合は、移行後に手動で実装し直す必要があります。

2. 生成された設定の調整

自動生成された設定ファイルの基本的な構造は正しいものの、プロジェクト固有の調整が必要でした。

const { defineConfig, globalIgnores } = require("eslint/config");
const globals = require("globals");
const { FlatCompat } = require("@eslint/eslintrc");

const compat = new FlatCompat({
    baseDirectory: __dirname,
    recommendedConfig: js.configs.recommended,
});

module.exports = defineConfig([
    {
        languageOptions: {
            globals: {
                ...globals.browser,
                ...globals.node,
                // プロジェクト固有のグローバル変数
            },
        },
        // ルール設定など
    },
    // TypeScript、Vue.js用の設定
]);

3. プロジェクト固有の課題への対応

私たちのプロジェクトでは、以下の点で調整が必要でした。

  • CommonJS形式の維持:プロジェクト内にCommonJS形式のコードが残っているため、package.jsontypemoduleに変更せず、設定ファイルもCommonJS形式で記述
  • Vue 2のルールに変更:移行ツールが生成したファイルはvue3-recommendedを使用していたため、現在のプロジェクトに合わせてVue 2のルールに変更
  • プラグインの対応確認:幸いなことに利用しているプラグインはFlat Configに対応していたため、FlatCompatを使用せずに移行できました

4. 最終的な設定ファイル

試行錯誤の結果、以下のような設定にまとまりました。

// eslint.config.mjs

import { defineConfig, globalIgnores } from "eslint/config";
import globals from "globals";
import eslintPluginVue from 'eslint-plugin-vue'
import pinia from 'eslint-plugin-pinia'
// その他の必要なインポート

export default defineConfig([
  js.configs.recommended,
  eslintConfigPrettier,
  ...eslintPluginVue.configs['flat/vue2-recommended'], // Vue 2用の設定
  pinia.configs["recommended-flat"],
  {
    languageOptions: {
      globals: {
        ...globals.browser,
        ...globals.node,
        ...globals.jest,
        // プロジェクト固有のグローバル変数
      },
    },
    // ルール設定
  },
  // TypeScript、Vue.js用の個別設定
  globalIgnores(["node_modules/*", "www/*", "res/*"])
]);

移行した結果

移行時に役立ったツール - ESLint Config Inspector

移行作業において特に役立ったのがESLint Config Inspectorです。

github.com

以下のコマンドで起動できます。

$ npx @eslint/config-inspector --config eslint.config.mjs

このツールを使うことで、以下のような情報を簡単に確認できました。

  • 現在適用されているルールとその設定値
  • 各ファイルパターンに対してどのルールが適用されているか
  • プラグインとその設定の一覧
  • 無効化されているルールの確認

複数の設定が重なり合う複雑な構成でも、最終的にどのルールが適用されているかを一目で把握できます。これにより、移行後の設定が意図通りに動作しているかを確認でき、設定の重複や矛盾を発見しやすくなりました。

Flat Config形式の利点

Flat Config形式に移行したことで、以下のような利点がありました。

  • 設定ファイルがJavaScriptモジュールとして記述できるため、条件分岐や動的な設定が容易になりました
  • 設定の継承や上書きがより明確になり、設定の優先順位を把握しやすくなりました
  • プラグインやパーサーの設定がより直感的になりました

特に、複数の設定ファイルが存在していた従来の形式と比べて、単一のファイルで全体を管理できるようになったことは大きな改善でした。

まとめ

Flat Config形式への移行により、以下の成果を得ることができました。

  • 設定ファイルの一元管理による保守性の向上
  • より直感的で柔軟な設定記述
  • ESLint Config Inspectorによる設定の可視化
  • 将来のESLint v10への互換性の確保

ESLint v10では従来のeslintrc形式が廃止される予定のため、早期の移行により将来的な互換性を確保できました。

Flat Config形式を採用することで、設定ファイルの見通しがよくなり、メンテナンスにかかる時間を削減できます。ぜひ参考にしていただければ幸いです。