Closed22

【ESLint】Legacy ConfigからFlat Configへ移行するための情報収集をしたい

1zushun1zushun

モチベーション

過去にESLint周りの記事を書いていたのでこちらをFlat Configにする。その後に本業のFlat Config移行に着手する

https://zenn.dev/shuuuuuun/articles/127728961f89a0

完了。今回のFlat Config 移行でaribnbのルールセットの利用をやめた。以下のissueを見るとわかるが結構つらそう。20250101時点でもFlat Configへの対応ができていない?

https://github.com/AlesInfiny/maia/issues/1343

本業の方の移行も完了🎉

1zushun1zushun

Flat Config へ移行する背景

  • ESLint v8 は2024/10/05でEOLを迎えた(ref
  • ESLint v9 でFlat Configがデフォルトになり、eslintrc は非推奨になる
  • ESLint v10 (2024年末〜2025 年初頭にリリース予定)で eslintrc が削除される(ref

-> eslintrcからFlat Configへの移行しない場合、ESLint v10以降のバージョンアップができなくなってしまう。

想定している取り組み

8系でもv8.21.0(2022/08/01リリース)以降であればFlat Configが使用可能なので、まずはFlat Configへの移行させることをゴールにする。余裕があれば v9 へのバージョンアップまで着手する。

-> 結局 ESLint Config Inspectorを使って作業をしたかったのでv9へ上げてからFlat Configへの移行作業に着手した。

想定している作業は以下。

  • 使用しているextend, plugin, ruleがFlat Config対応しているかの調査
  • マイグレーションガイド(ref)に従ったFlat Configへの移行
  • カスタムルールをFlat Configに対応させる(ref
  • Flat Configを有効にするために.vscode/settings.jsonを修正する(ref
  • ルールが新旧で一致しているかの確認 etc

「具体的にどうやってやるか?」は以下の記事が参考になりそう。

https://www.wantedly.com/companies/wantedly/post_articles/939693

https://tech.smarthr.jp/entry/eslint_v9

1zushun1zushun

Flat Config にすると何が嬉しいのか?

Flat Configに至るまでの背景が書いてある。

https://eslint.org/blog/2022/08/new-config-system-part-1/

その中でも触れられているが、Flat Configへ移行することによるメリットは大きく2つあるので以下の引用記事も交えながら見ていくと良いかも。

プラグインを自分で解決しなくなる!

override や extends という概念がなくなる!

  • https://zenn.dev/cybozu_frontend/articles/about-eslint-flat-config
    • FlatConfig は override や extends という概念をなくし、代わりに configuration object と呼ばれる各設定情報を要素とする配列で表現するようになりました。
  • https://zenn.dev/babel/articles/eslint-flat-config-for-babel
    • このカスケーディングの機構は、従来の.eslintrcが持っていた 2 つの機構を統合するものです。つまり、extendsで再利用可能な設定を読み込む機構と、overridesにより一部のファイルのみ設定を変えられる機構です。両者はネスト可能(extendsをたどるとoverridesがあったり、overridesの中でextendsできたり)であったため、従来は設定ファイルのカスケーディングが木構造の上で行われていたことになります。
  • https://tech.smarthr.jp/entry/eslint_v9
    • カスケード構造が廃止され、設定がフラット化されることで、適用範囲やルールの構造が直感的に理解できるようになります
1zushun1zushun

Introducing ESLint Compatibility Utilities

Flat Configへの変更に伴って「Rule APIの変更」と「Flat Configへの変更」の2点が必要になる

https://eslint.org/blog/2024/05/eslint-compatibility-utilities/

@eslint/eslintrc (ex: flatCompat.extends)

Rule APIの変更

https://github.com/eslint/eslintrc

The primary class in this package is FlatCompat, which is a utility to translate ESLintRC-style configs into flat configs

カスタムルールを作るときにcontext.getSourceCode()でアクセスするとdeprecatedの警告が表示されcontext.sourceCodeを使うように促されるので、新しくルールを作るとき、または変更する時は見つけやすいはず。

https://eslint.org/blog/2023/09/preparing-custom-rules-eslint-v9/

@eslint/compat(ex: fixupConfigRules)

Flat Configスタイルへの変更

https://www.npmjs.com/package/@eslint/compat

you may not be able to access each of the plugins that are referenced inside of an eslintrc-style configuration. In that case, you can use the fixupConfigRules() function to wrap all plugins

なのでラップすることでeslintrc-styleからflat-config-styleに変えてくれる

https://qiita.com/ljourm/items/0c98f342d437ed3a8563#eslint-8系と9系のflat-config以外の違い

https://medium.com/@1608naman/a-flat-attempt-at-the-eslint-flat-config-393005212d67

カスタムルールをFlat Configに対応させる

対応自体は思ったより簡単だった。公式docsをちゃんと読めばそこまで大変ではなさそう。

Rule APIの破壊的変更の対応

https://eslint.org/blog/2023/09/preparing-custom-rules-eslint-v9/#context.getancestors()

RuleTesterも直す

https://eslint.org/docs/latest/integrate/nodejs-api#ruletester

1zushun1zushun

@eslint/js

https://github.com/eslint/eslint/tree/main/packages/js

recommendedの中身は純粋なルールの定義がされている

https://github.com/eslint/eslint/blob/main/packages/js/src/configs/eslint-recommended.js#L19-L83

以下のようにnameを追加すると

const jsConfig = [
  {
    name: 'js recommended',
    ...eslint.configs.recommended,
  },
  {
    name: 'js override',
    rules: {
      'no-undef': 'off',
    },
  },
]

こんな感じになるのでデバッグしやすくなる

1zushun1zushun

typescript-eslint

いくつか記事を見たけれどtseslint.configは使わない想定で進めたい。

https://typescript-eslint.io/packages/typescript-eslint#config

もちろんtseslint.configでラップするメリットはあるが以下理由から使わなくても良いかなと。

  • typescript-eslintの独自プロパティ(extendsプロパティ)が生え、コード記法を統一できない可能性がある(PRで弾くしかなさそう)
  • そもそもtseslint.configの影響が大きすぎる。責務として抱え込みすぎな気がする。
  • ある程度作ってきたけど、tseslint.configを使わないことで致命的な後戻りはなさそう。

tseslint.configを使わずにtypescript-eslintみたいな配列でconfig object(正式にはConfiguration Objectと呼ぶ)を受け取るかつ、例えばfilesの対象を上書きした場合は以下のような実装をする必要がある。

https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/typescript-eslint/src/config-helper.ts#L52-L55

同僚と話してやはりtseslint.configは使わない方針になった。理由は以下。

  • tseslint.configがただのeslintに対する便利関数である点
  • 「...config or config」「extends 使う使わない」など記法が増えてしまう点
  • 今後eslint側からdefineConfigなるtseslint.configに似たものが出るよう点(ref

「TypeScriptがカバーしているため、不要なESLintの推奨ルールを無効にします」とのこと。recommended, recommended-type-checkedなどを指定するときに一緒に読み込まれている。以下のdocsにも明記されている

https://typescript-eslint.io/users/configs/#recommended-type-checked-only

https://github.com/typescript-eslint/typescript-eslint/blob/3ae4148d48ea73de4055dcdf8becdaad6d7c928e/packages/eslint-plugin/src/configs/eslint-recommended-raw.ts#L10-L47

ちなみに「TypeScriptがカバーしているため、不要なESLintの推奨ルールを無効にします」に関してはeslint-plugin-importでも対応が必要になる(以下参照)

https://zenn.dev/link/comments/0ea88681048d3f

base

baseも呼ばれていたので一応メモする。baseは以下を参照すれば良い。docsにも記載されている。

https://typescript-eslint.io/users/configs/#base

https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/src/configs/base.ts

recommendedとrecommended-type-checkedの違い

recommendedとrecommended-type-checkedってどのくらい差分あるんだろうか?
-> recommended + recommended-type-checked-only = recommended-type-checked

例えば以下のルールはリンクを見てみるとrecommendedって書いたあるけどrecommended-type-checkedでも呼ばれているので念頭に置いたおきたい。呼びたくない時はrecommended-type-checked-onlyを使えば良い。

'@typescript-eslint/no-require-imports': 'off', // https://typescript-eslint.io/rules/no-require-imports/
'@typescript-eslint/no-unused-expressions': 'off', // https://typescript-eslint.io/rules/no-unused-expressions/
'@typescript-eslint/no-unused-vars': 'off', // https://typescript-eslint.io/rules/no-unused-vars/
'@typescript-eslint/no-empty-object-type': 'off', // https://typescript-eslint.io/rules/no-empty-object-type/

https://typescript-eslint.io/users/configs/#recommended-type-checked-only

1zushun1zushun

Combine Configs

https://eslint.org/docs/latest/use/configure/combine-configs

sharerable configがObject形式かArray形式かで微妙に適用方法が異なる。すでに設定されているfilesを上書きする方法(部分的に上書きする方法)も記載されている。通常のJavaScriptと同じような感じなのでFEを触っているなら違和感はないはず。

sharerable configでArray形式なのは例えばtypescript-eslint/recommendedstorybook/recomenndedが該当する。Object形式だと@eslint/jseslint-plugin-reacteslint-plugin-importが該当する。ここら辺はREADMEを見るか直接コードを見てどういう形式でexportされているか確認する必要がありそう。

なのでよく記事で見る@eslint/jstypescript-eslintの適用でtypescript-eslintだけ展開されているのはArray形式だったから。という前提を知っておく必要がある。

[MEMO]いい感じのexがあれば添付する

また、以下の記事でも注意書きされているがObject形式の場合はマージ方法に注意しないとrulesを上書きしたつもりがshareable configで設定しているルールを全て上書きする可能性があるので気をつけること。

https://susisu.hatenablog.com/entry/2024/08/14/233156

1zushun1zushun

トラブルシュート

外部モジュールとして切り出したファイル変更を ESLint Config Inspector で検知できない

表題の通り。eslint.config.jsの変更自体は検知できるので、中で差分があれば即時反映してくれる(ex: rulesの変更とかnameの変更など)しかし外部に切り出したファイルの変更は再度npx eslint --inspect-configを叩かないと反映されない。

SyntaxError: Cannot use import statement outside a module

以下の記事で取り上げられていた。package.jsonのtypeをmoduleに変更して解決。全部.mjs(外部モジュールも含めて)で進めるか.jsでpackage.jsonのtypeをmoduleに変更するかになりそう。

https://qiita.com/Shilaca/items/c494e4dc6b536a5231de#commonjs-なプロジェクトでも-es-module-形式で書きたいsyntaxerror-cannot-use-import-statement-outside-a-module-が出る

ちなみにFlat Configの拡張子.mjsサポートはされていて、むしろ前は.jsのみのサポートだったのでプロジェクトのpackage.jsonのtypeに依存して、中身がCommonJSかESMなのかが変わってしまう負の側面があったそう。

https://zenn.dev/teppeis/scraps/c62621db4384d2

TypeScriptで設定ファイルを書けるeslint.config.tsのサポートが可能になった。カスタムルールをいちいちトランスパイルする必要なくなった?

https://eslint.org/blog/2025/01/eslint-v9.18.0-released/

1zushun1zushun

ぼやき

初めは以下のようにsharable config(+最低限のoverride)とoverrideのconfig objectを分けるように書いていたが、ESLint Config Inspectorでみると結局何がoverrideされているか見えにくい。

export const importConfig = [
  {
    ...pluginImport.flatConfigs.recommended,
    name: 'import recommended',
    files: ['**/*.{ts,tsx}'],
  },
  {
    name: 'import recommended override',
    files: ['**/*.{ts,tsx}'],
    rules: {
      'import/named': 'off',
      'import/namespace': 'off',
      'import/default': 'off',
      'import/no-named-as-default-member': 'off',
      'import/no-unresolved': 'off',
    },
  },
]

なので一つのconfig objectにまとめると見やすくなる。1プラグインで1config objectにした方が良さそう。冗長的に書いていたfilesなども不要になるので良さそう。

export const importConfig = [
  {
    ...pluginImport.flatConfigs.recommended,
    rules: {
      ...pluginImport.flatConfigs.recommended.rules,
      'import/named': 'off',
      'import/namespace': 'off',
      'import/default': 'off',
      'import/no-named-as-default-member': 'off',
      'import/no-unresolved': 'off',
    },
    name: 'import recommended',
    files: ['**/*.{ts,tsx}'],
  },
]

1zushun1zushun

デバッグ

v9になっているなら基本はESLint Config Inspectorを使ったデバッグでokだと思う。これの登場でかなり触りやすくなった気がする。

--print-config オプション

現在適用されているルールを確認することができる。ただルールの量が多いとみるのが大変かもしれない。工夫をすればスナップショットテストができるのでESLintの知見がない人でも安心して改修に着手できるので試してみたい。

npx eslint --print-config <filename> > output.json

https://zenn.dev/nananaoto/articles/9968d8f3966e90a46229

https://zenn.dev/wakamsha/articles/test-eslint-config

ESLint Config Inspector

スクラップの中で何回かすでに登場していたが改めて。添付の記事が画像付きで説明しているので雰囲気掴みたい人はどうぞ。

https://eslint.org/docs/latest/use/command-line-interface#--inspect-config

https://qiita.com/KokiSakano/items/55fc416cbaa6edb2bf20

1zushun1zushun

Tipsや作業ログをまとめています。

プラグインの Flat Config 対応状況を確認したい

以下をウォッチしておくと良さそう。

https://github.com/eslint/eslint/issues/18093

Flat Configに型定義を当てたい

以下の通り。

npm i -D @types/eslint
/** @type {import("eslint").Linter.FlatConfig[]} */
export default [ ]

https://dackdive.hateblo.jp/entry/2024/06/25/100000

Parsing error: Unexpected token エラーが発生する

おそらくparserの設定がおかしいのでそちらを確認する
(ex: @typescript-eslint/parser を設定していない等)

.vscode/settings.jsonの設定を変える

筆者はv9まで上げたので対応不要。

https://zenn.dev/gangannikki/articles/12bdae5236c846

.eslintignoreを削除する

--ignore-pathで指定している、または.eslintignoreでしている場合はFlat Configのignoresに移動させる

export default [
    // ...other config
    {
        // Note: there should be no other properties in this object
        ignores: ["**/temp.js", "config/*"]
    }
];

https://eslint.org/docs/latest/use/configure/migration-guide#ignoring-files

npm scriptの修正

// "lint:js": "eslint --ext .tsx,.ts app/",
"lint:js": "eslint 'app/**/*.{tsx,ts}'",

--ext が廃止になった。--ext .ts,.tsxを使っている場合は以下のようにする必要がある

export default [
    {
        files: ["**/*.ts", "**/*.tsx"]
        // any additional configuration for these file types here
    }
];

https://eslint.org/docs/latest/use/configure/migration-guide#--ext

1zushun1zushun

graphql-eslint

v3系のままFlatConfigに対応させるようと思ったが、最新の記事が散見し期待した記事が見つけにくい状態だったので直接該当のバージョンのコードを見にいった(以下参照)

既にv3のタイミングからFlat Config対応はされていた模様。

https://github.com/graphql-hive/graphql-eslint/tree/%40graphql-eslint/eslint-plugin%403.20.1

docsはこちら。

https://the-guild.dev/graphql/eslint/docs

parser: pluginGraphql.parser(v4のparserの読み込み方法)にしたら10分以上解析に時間がかかった。一応解析は進むけどすごく遅くなる。parser: pluginGraphql(v3のparserの読み込み方法)にすると期待している速さになった。

これに気づくの遅れてtypescript-eslintの型チェックの解析が遅いのか?config objectが多すぎたのか?と少し遠回りしてしまった。

次にCannot destructure property 'schema' of 'context.parserServices' as it is undefined.のエラーが出た。fixupPluginRulesを当てることで解決。Flat Configに対応していないRule APIを使っていたのが原因。

対応としては以下と同じ。

https://github.com/graphql-hive/graphql-eslint/issues/2178#issuecomment-2171628289

context.getScope -> context.sourceCodeに破壊的変更があったのをカスタムルールを作るときに知っていたので、おそらくRule APIが原因だろうなと目安が立っていたので速攻で直せた。

類似の記事は以下になる。

https://bufferings.hatenablog.com/entry/2024/11/24/211641

Flat Configではnext lintがrun commandで使えないためnpx eslint filename --cacheをしていたがgraphql-eslintのv3はどうやら対応されていないようなのでv4に結局あげた。

詳細は次の記事になる。

https://github.com/graphql-hive/graphql-eslint/issues/2178#issuecomment-2261600240

documentsの指定をしておらずエラーが発生した。指定したらいくつかエラーが発生した。おそらくv3だとdocumentsの指定は強制されておらず、その分解析から漏れていたのかなと。

Fragmentをファイルを跨いで使用している場合、単一ファイルだけでは情報が足りず、ルールが正しく適用されない可能性があります。

https://zenn.dev/buyselltech/articles/1c21a54d8c6cf3#documents

その他参考になりそうな記事

https://github.com/graphql-hive/graphql-eslint/issues/2178

1zushun1zushun

eslint-config-next(14.2.22)

@next/next/no-duplicate-head@next/next/no-page-custom-fontで以下のエラーが発生する。
で、これも今までと同じ原理でRules APIの対応ができていないのが原因なためfixupPluginRulesでラップする必要がある。

詳細までは追っていないが公式のアナウンス通りならv15に上げると直るかも。

@next/next/no-page-custom-font context.getAncestors is not a function

next lint でエラーが発生する

以下のissueと同じ事象が発生している。

https://github.com/vercel/next.js/issues/64409

v15に上げると直るぽい。

https://github.com/vercel/next.js/issues/64409#issuecomment-2411304733

しかしまだv15に上げる見込みはないのでv14でnext lint相当の動きができるようにセットアップする必要がある。このときに--cacheオプションを使う必要がある(next lintではデフォルトでキャッシュが効いている)が--cacheオプションはgraphql-eslint v3では対応されていないためv4に上げる必要がある(以下参照)

https://zenn.dev/link/comments/0925834fea9652

1zushun1zushun

eslint-plugin-import

https://www.npmjs.com/package/eslint-plugin-import

recommendedは問題ないけどimport/typescriptplugin:import/typescript)はFlat Config対応されていないようなのでFlat Compatを使った対応をする必要がある。

https://github.com/import-js/eslint-plugin-import/blob/main/config/typescript.js

あとは、できたらくらいの温度感だがtypescript-eslintを使っているので不要なルールはOFFにしておきたい。

https://typescript-eslint.io/troubleshooting/typed-linting/performance/#eslint-plugin-import

[追記]20250218

import/typescriptのFlat Config対応されていた。ドキュメントが更新されていなかったぽい。

https://github.com/import-js/eslint-plugin-import/blob/main/README.md#config---flat-with-config-in-typescript-eslint

以下のPRで更新されていた

https://github.com/import-js/eslint-plugin-import/pull/3138

1zushun1zushun

eslint-plugin-jsx-expressions

https://www.npmjs.com/package/eslint-plugin-jsx-expressions

以下のエラーが発生する。

Error: Error while loading rule 'jsx-expressions/strict-logical-expressions': You have used a rule which requires parserServices to be generated. You must therefore provide a value for the "parserOptions.project" property for @typescript-eslint/parser.

こちらのissueと全く同じ状態。

https://github.com/hluisson/eslint-plugin-jsx-expressions/issues/18

で、こっちで修正PRが立てられているのでマージされたら直りそう。ということで一時的にfixupPluginRulesで対応する。

https://github.com/hluisson/eslint-plugin-jsx-expressions/pull/19

1zushun1zushun

eslint-plugin-react-hooks

React Hook "useDisclosure" is called in function "〇〇: FC<Props>" that is neither a React function component nor a custom React Hook function. React component names must start with an uppercase letter. React Hook names must start with the word "use".

関数コンポーネントの命名を日本語にしていた場合、最新のrules-of-hooksを当てるとエラーになる。ヒストリからどういった変更が加えられたか確認できていないので手隙で見ておきたい。

https://github.com/facebook/react/commits/main/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js

おそらくの以下の部分で日本語が弾かれてしまう

https://github.com/facebook/react/blob/main/packages/eslint-plugin-react-hooks/src/RulesOfHooks.js#L49

https://legacy.reactjs.org/docs/hooks-rules.html

-> 確認した結果、それっぽいルール変更があったのでバージョンを下げる必要がある。

以下でインストールできるバージョンを探す。

pnpm view eslint-plugin-react-hooks versions

eslint-config-nextのv14.2.2ではeslint-plugin-react-hooksはv4.5を使っていたこともあったので、v4.5まで下げて解決。

https://github.com/vercel/next.js/blob/v14.2.2/packages/eslint-config-next/package.json#L21C2-L21C77

1zushun1zushun

typescript-eslint v8 の破壊的変更について

Flat Config移行に際しtypescript-eslintをv8まで上げたがいくつか変更があったらしく、見逃していたのでメモしておく。

Announcing typescript-eslint v8

基本は以下の通りだが実際に修正した箇所について少し触れていく

https://typescript-eslint.io/blog/announcing-typescript-eslint-v8#rule-breaking-changes

  • @typescript-eslint/prefer-ts-expect-error
    • 利用していなかったためスキップ
  • @typescript-eslint/no-var-requires
  • @typescript-eslint/no-throw-literal
    • 利用していなかったためスキップ
  • @typescript-eslint/no-useless-template-literals
    • 利用していなかったためスキップ
  • @typescript-eslint/no-loss-of-precision
    • no-loss-of-precisionを有効にする(既に有効になっていたため対応不要)
  • eslint.style
    • 利用していなかったためスキップ
  • @typescript-eslint/prefer-nullish-coalescing
    • ignoreConditionalTestsのデフォルトがfalse -> trueになった。静的解析で引っかかってなさそうなで大丈夫なそう
  • @typescript-eslint/no-unused-vars
  • @typescript-eslint/ban-types
    • @typescript-eslint/no-empty-object-type にリプレイス

メモ

Flat Configへのリプレイスが終わった後に判明したのでLegacyでどういったルールが適用されているか知っておかないと上記の破壊的変更の修正ができない。筆者の場合は作業ログを取っていてprint configを使ってLegacyのルールのバックアップを取っていたので助かった。

もしFlat Config移行を検討されている方がいらっしゃったらバックアップをとっておくと良いかもしれない。

1zushun1zushun

仕上げ

移行が完了した後に見つけた

移行で気を付けるポイントは以下。筆者も同様のことを考えていて、特に2個目に関してはprint-debugで照らし合わせて人力でやった。

  • lint を適用するファイルの範囲が同じか?
  • すべてのファイルで適用されている rule・および設定、option が変わっていないか?

https://zenn.dev/cybozu_frontend/articles/introduce-eslint-config-compat

1zushun1zushun

まだ続く

no-restricted-syntaxが複数箇所使われていてルールとしては有効になっているものの上書きされてしまっていて、一部無効化させていた。結構気を遣ってno-restricted-syntaxしないと思わぬ穴になりそうかもしれない

例えばsharable configでno-restricted-syntaxが使われている場合は以下のようにoverrideする必要があったり。

https://zenn.dev/pirosikick/articles/f57c573282b3d8

Flat Configが終わった後の後片付け

  • 移行に伴ってOFFにしたreportUnusedDisableDirectivesを有効にする
  • 移行に伴ってOFFにしたtypescript-eslintを有効にする
  • 移行に伴ってOFFにしたgraphql-eslintを有効にする
  • 無効化されていたno-restricted-syntaxを有効にする + ASTのリファクタ
  • eslint-plugin-jsx-a11yを導入する
  • 骨子となるconfig objectを外部モジュールに切り分けてeslint.config.mjsは上書きする設定のみ配置する

プラグインのバージョンを上げる時に気をつけること

単純にBreaking Changeがないか確認しておく

例えば今回の移行で言うならtypescript-eslintとかgraphql-eslintが該当する

https://github.com/graphql-hive/graphql-eslint/issues/981

https://zenn.dev/link/comments/dad4aa7f24afae

1zushun1zushun

TODO

  1. rules配下のcjsファイルを削除する
  2. rules配下のmjsをconfigsに移動させる
  3. カスタムルールをTypeScriptで書けるようにする
  • import/typescriptでcompat.extendsしている箇所を削除する
  • eslint-plugin-next, eslint-plugin-react-hooksのfixupPluginRulesを削除する
  • eslint-plugin-jsx-expressionsは2年放置されているので代替ルール用意した方が良さそう
  • カスタムルールは実装PR、適用PRで分けた方が良さそう
  • カスタムルール作成のTips esaを書く
1zushun1zushun

[追記]defineConfig

ざっくりとみてみると

  • 型安全にする
  • 配列またはオブジェクトで提供されるプラグインを平す
  • JS初心者にもmodificationを楽にする

extends(defineConfig)を再導入した

Ultimately, we realized that the best way to solve this set of problems was to reintroduce extends. The defineConfig() function allows you to specify an extends array in any object, and that array can contain objects, arrays, or strings (for plugin configs that follow the recommended approach). This allows you to rewrite your configuration file in a more consistent way:

https://eslint.org/blog/2025/03/flat-config-extends-define-config-global-ignores/

で、以下のスクラップで触れていたtseslint.configと同じじゃんという感想。上記のdocsでは代替としては名言されていなかった。

https://zenn.dev/link/comments/1a48c002595c12

このスクラップは4ヶ月前にクローズされました