FlatConfig移行時に知っておくとよいかもしれないこと
はじめに
こんにちは。
2024年はESLint v8がEOLになったり、Next.jsがESLint v9をサポートしたりで設定ファイルをFlat Config
形式に移行した方が多いかもしれません。
私自身、業務でそれなりに大きいプロジェクト2つで移行を経験しました。
今回はそこで得た知見をまだ移行していない方向けに書き連ねてみようと思います。
知っておくとよいかもしれないこと
移行ツールを使う
初手は移行ツールで移してしまうのがオススメです。
公式ドキュメントにある通り、ESLintが移行ツールを提供しています。
こちらはFlatCompat
を使って、ざっくりと移行できるツールになっています。
.eslintrc.js
では上手く動作しないケースがあるようですが、とりあえずこれで移行しておくとコマンドを実行できる状態は担保できます。
npx @eslint/migrate-config .eslintrc.json
エディタの設定を変更する
vscodeを利用されている方は.vscode/settings.json
からeslint.useFlatConfig
を有効化しましょう。
移行作業中はLegacy Configと行ったり来たりということがよくあるので、プロジェクトフォルダにローカル設定として追加するのがオススメです。
これを忘れるとエディタ上にエラーが表示されなくなりますので、最初のうちに変更してしまいましょう。
typescript-eslint
を使用する
typescript向けの設定でよく@typescript-eslint/parser
や@typescript-eslint/eslint-plugin
が開発パッケージに含まれています。
あまりシビア出ない方はtypescript-eslint
のパッケージにまとめてしまうことをお勧めします。
typescript-eslint
で利用できるconfig
関数を使うことで、設定を型補完がある状態で記載できます。
このconfig
関数は単に型を提供するだけでなく、以下の機能を提供します。
-
extends
extendsを利用することで、設定をある程度まとめることが可能となります。// extendsを利用した書き方 export default tseslint.config({ files: ['**/*.ts'], extends: [ eslint.configs.recommended, tseslint.configs.recommended, ], rules: { '@typescript-eslint/array-type': 'error', '@typescript-eslint/consistent-type-imports': 'error', }, }); // ↓と同じ export default tseslint.config( eslint.configs.recommended, tseslint.configs.recommended, { files: ['**/*.ts'], rules: { '@typescript-eslint/array-type': 'error', '@typescript-eslint/consistent-type-imports': 'error', }, } )
-
内部で配列をフラットにしてくれる
Flat Configではtseslint.configs.recommended
のように配列の設定を利用する場合、スプレッド構文を利用する必要があります。
これは利用する設定により異なりますが、mjs
で記述する場合、どれが配列でどれがオブジェクトなのかがかなりわかりにくいです。
このヘルパー関数は内部で配列を展開してくれるため、利用者側がツール側の設定の構造を意識せずに設定することが可能となります。// ヘルパー関数を利用しない export default [ eslint.configs.recommended, ...tseslint.configs.recommended, { /*... */ }, // ... ]; // ヘルパー関数を利用する export default tseslint.config( eslint.configs.recommended, tseslint.configs.recommended, { /*... */ }, // ... );
tsconfig
を作成する
設定ファイル用のtypescript用の設定でparserOptions.project
に既存のtsconfig.json
を指定していると画像のようなエラーが表示されるケースがあります。
これは対象のファイルがtsconfig.json
のincludes
に含まれていないことが原因です。
エラー内容の通りですが、解決方法としては以下のような選択肢があります。
- ESLintの対象ファイルからこのファイルを外す
-
tsconfig.json
のincludes
に設定ファイルを追加する - 新しく設定ファイルを含める設定をした
tsconfig.xxx.json
を作成し、それをparserOptions.project
に指定する
個人的には一番最後のtsconfig.xxx.json
を作成する方法がオススメです。
この方法にしておくとあまり考えることなく追加でき、tsc
の実行時は含めないということが可能になります。
設定の例は以下の通りです。
{
"extends": ["./tsconfig.json"],
"compilerOptions": {
"allowJs": true
},
"include": ["**/*.ts", "eslint.config.mjs"]
}
export default tseslint.config({
// ...
languageOptions: {
parserOptions: {
projectService: "tsconfig.eslint.json", // 新規作成したtsconfigを指定
},
},
});
name
プロパティを指定する
各オブジェクトレベルの設定にname
を指定できます。
一番の理由はeslint/config-inspector
で確認する際にわかりやすいという理由です。
しかしながらconfig-inspector
を使わない場合でもこの設定は何の設定なのかの認識コストが下がるのでオススメです。
export default [
{
name: "project/ignore",
/*... */
},
{
name: "project/xxx",
/*... */
},
{
name: "project/yyy",
/*... */
},
];
プラグインを自作する
以前の設定では自作のルール・プラグインの導入にeslint-plugin-local-rules
やeslint-plugin-rulesdir
といった追加のプラグインが必要でした。
しかしながら、Flat Configではこれらは必要ありません。ローカルルールやプラグインは他のjsファイル同様にimport
, require
で使用できます。
/** @type {import('eslint').Rule.RuleModule} */
const rule = {
meta: {/*... */},
create: () => {/*... */}
}
export default rule;
import yyyRule from "./rules/yyy.mjs"
/** @type {import('eslint').ESLint.Plugin} */
const plugin = {
meta: {
name: "eslint-plugin-xxx"
},
rules: {
yyy: yyyRule,
// ...
},
configs: {/*... */},
}
export default plugin;
import xxxPlugin from "./eslint/eslint-plugin-xxx.mjs"
export default tseslint.config({
name: "project/root"
plugin: {
xxx: xxxPlugin
// ...
},
rules: {
"xxx/yyy": "error"
// ...
}
});
eslintのcliを直接使用する
これはnext lint
を使用している方向けです。
v15.1.7
時点でnext lint
はESLint v9での追加オプションに対応していません。
例えば、Gitフックでステージ上のファイルに対して実行する際に、指定したファイルがignores
に含まれていると警告が出ます。
ESLint v9のcliでは--no-warn-ignored
というオプションにより無効化できますが、next lint
では未サポートです。
利用されるプロジェクトによっては同じようなケースがあるかと思いますので、サポートされるまでは直接ESLintのcliを実行することも手段として持っておくとよいです。
まとめ
今回はFlat Config移行へのTipsをまとめてみました。
ありきたりではありますが、知っていたり気を付けたりすることで設定を移行しながら改善できることは多いです。
何かしら皆さんのお役に立てれば幸いです。
Discussion