Uniforceのニシです。

この記事を書いている頃は、ヤマザキパンのベイクワンシリーズのミニメロンクロワッサンにハマっています(甘い飲み物、食べ物、好き🤤)。

さて、今回はESLintのバージョンアップに伴う構成ファイルのマイグレーションのお話です。

きっかけ

npm-check-updatesでパッケージの更新情報を確認してみると、いくつかのパッケージがアップデートできることが分かりましたので、これらのパッケージのアップデートを実施しました。

 $ ncu
@types/jest ^29.5.12 → ^29.5.13
@types/node 20.12.7 → 22.7.4
@typescript-eslint/eslint-plugin ^7.7.1 → ^8.8.0
@typescript-eslint/parser ^7.7.1 → ^8.8.0
aws-cdk 2.138.0 → 2.161.0
aws-cdk-lib 2.138.0 → 2.161.0
cdk-nag ^2.28.104 → ^2.28.195
constructs ^10.0.0 → ^10.3.0
eslint ^8.57.0 → ^9.11.1
prettier ^3.2.5 → ^3.3.3
ts-jest ^29.1.2 → ^29.2.5
typescript ~5.4.5 → ~5.6.2

パッケージのアップデートにより、ESLintのバージョンを8.57.0から9.11.1に更新しました。

その後、eslintコマンドを実行すると、次のエラーに遭遇しました。

$ npx eslint 

(node:316979) ESLintIgnoreWarning: The ".eslintignore" file is no longer supported. Switch to using the "ignores" property in "eslint.config.js": <https://eslint.org/docs/latest/use/configure/migration-guide#ignoring-files>
(Use `node --trace-warnings ...` to show where the warning was created)

Oops! Something went wrong! :(

ESLint: 9.11.1

ESLint couldn't find an eslint.config.(js|mjs|cjs) file.

From ESLint v9.0.0, the default configuration file is now eslint.config.js.
If you are using a .eslintrc.* file, please follow the migration guide
to update your configuration file to the new format:

<https://eslint.org/docs/latest/use/configure/migration-guide>

If you still have problems after following the migration guide, please stop by
<https://eslint.org/chat/help> to chat with the team.

どうやらv9からサポート対象のファイルが変更になったようです。

メッセージにある通り、移行ガイドを参照しながら解決していきたいと思います。

構成ファイルをマイグレーション

移行マイグレーションを実施する前のディレクトリ構成のイメージはこちらの通りです。

.
├── .eslintignore
└── .eslintrc.json

ファイルの中身は次の通りです。

.eslintignore:

**/node_modules/**
**/cdk.out/**
*.js
*.d.ts

.eslintrc.json:

{
"extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": "./tsconfig.json"
},
"plugins": ["@typescript-eslint"],
"rules": {}
}

それでは構成ファイルのマイグレーションを実施していきたいと思いますが、移行ガイドを見るとnpx @eslint/migrate-config .eslintrc.json を実行すれば良さそうです。さっそくマイグレーションのコマンドを実行してみます。

$ npx @eslint/migrate-config .eslintrc.json
Need to install the following packages:
@eslint/migrate-config@1.3.0
Ok to proceed? (y) y

Migrating .eslintrc.json
Also importing your .eslintignore file

Wrote new config to ./eslint.config.mjs

You will need to install the following packages to use the new config:
- @eslint/js
- @eslint/eslintrc

You can install them using the following command:

npm install @eslint/js @eslint/eslintrc -D

新しく eslint.config.mjs というファイルを作成してくれたようです。案内に従ってnpm installも実行しておきます。

$ npm install @eslint/js @eslint/eslintrc -D

removed 1 package, and audited 1001 packages in 2s

122 packages are looking for funding
run `npm fund` for details

found 0 vulnerabilities

ここまででディレクトリ構成は次の通りに変わりました。

.
├── .eslintignore
├── .eslintrc.json
└── eslint.config.mjs

生成された eslint.config.mjsの中身を確認してみました。

import typescriptEslint from '@typescript-eslint/eslint-plugin';
import tsParser from '@typescript-eslint/parser';
import path from 'node:path';
import { fileURLToPath } from 'node:url';
import js from '@eslint/js';
import { FlatCompat } from '@eslint/eslintrc';

const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});

export default [
{
ignores: ['**/node_modules/**/*', '**/cdk.out/**/*', '**/*.js', '**/*.d.ts'],
},
...compat.extends('eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'),
{
plugins: {
'@typescript-eslint': typescriptEslint,
},

languageOptions: {
parser: tsParser,
ecmaVersion: 5,
sourceType: 'script',

parserOptions: {
project: './tsconfig.json',
},
},

rules: {},
},
];

どうやら .eslintignore、.eslintrc.jsonの内容を基づいて設定をしてくれています。

.eslintignoreはignoresに入っています。.eslintrc.jsonは...compat.extends、plugins、languageOptions、rulesに入っています。

新しい設定ファイルを用意できましたので、eslintコマンドを実行してみます。

$ npx eslint
(node:322913) ESLintIgnoreWarning: The ".eslintignore" file is no longer supported. Switch to using the "ignores" property in "eslint.config.js": <https://eslint.org/docs/latest/use/configure/migration-guide#ignoring-files>
(Use `node --trace-warnings ...` to show where the warning was created)
=============

WARNING: You are currently running a version of TypeScript which is not officially supported by @typescript-eslint/typescript-estree.

You may find that it works just fine, or you may not.

SUPPORTED TYPESCRIPT VERSIONS: >=4.7.4 <5.6.0

YOUR TYPESCRIPT VERSION: 5.6.2

Please only submit bug reports when using the officially supported version.

=============

./eslint.config.mjs
0:0 error Parsing error: "parserOptions.project" has been provided for @typescript-eslint/parser.
The file was not found in any of the provided project(s): eslint.config.mjs

✖ 1 problems (1 errors, 0 warnings)

.eslintignoreが残っているとWarningが消えないようなので、.eslintignoreと.eslintrc.jsonを削除します。

また、@typescript-eslint/typescript-estreeがサポートしていないTypeScriptのバージョンを使用しているようなので、TypeScriptバージョンを5.5.4に変更します。

再度、eslintコマンドを実行してみます。

$ npx eslint

./eslint.config.mjs
0:0 error Parsing error: "parserOptions.project" has been provided for @typescript-eslint/parser.
The file was not found in any of the provided project(s): eslint.config.mjs

✖ 1 problems (1 errors, 0 warnings)

まだ./eslint.config.mjsのエラーが解消できていません。

.eslint.config.mjsを確認してみると1行目のインポート文でエラーが発生していました。エラー内容は次の通りです。

Parsing error: ESLint was configured to run on `<tsconfigRootDir>/eslint.config.mjs` using `parserOptions.project`: <tsconfigRootDir>/tsconfig.json
However, that TSConfig does not include this file. Either:
- Change ESLint's list of included files to not include this file
- Change that TSConfig to include this file
- Create a new TSConfig that includes this file and include it in your parserOptions.project
See the typescript-eslint docs for more info: <https://typescript-eslint.io/troubleshooting/typed-linting#i-get-errors-telling-me-eslint-was-configured-to-run--however-that-tsconfig-does-not--none-of-those-tsconfigs-include-this-fileeslint>

解決方法として提示された方法を確認して、今回は.eslint.config.mjsのignoreにmjs拡張子を除外する方法を選択しました。

変更前:

ignores: ['**/node_modules/**/*', '**/cdk.out/**/*', '**/*.js', '**/*.d.ts'],

変更後:

ignores: ['**/node_modules/**/*', '**/cdk.out/**/*', '**/*.js', '**/*.d.ts', '**/*.mjs'],

あらためてeslintコマンドを実行してみます。

$ npx eslint

(何も出力なし)

今度は特に問題も発生せずにコマンドを終了することができました!

まとめ

今回はESLintのバージョンアップに伴う構成ファイルのマイグレーションを実施してみました。移行ガイドに記載されているマイグレーションのコマンドを実行すれば、既存の設定を基に新しい設定ファイルを作成してもらえるので利用しているユーザーとしてはとても助かりました。元々の設定内容にもよると思いますが、マイグレーション後のエラーも解決することが難しいものではありませんでした。

バージョンアップに伴う構成ファイルのマイグレーションということで、作業するのに時間がかかるものと覚悟していましたが、スムーズに構成ファイルを移行することができて良かったです。

本日の記事はここまでとなります。

最後まで読んでいただきありがとうございました🙌