You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

升级ESLint至9.0.0时遭遇@typescript-eslint插件重复定义错误

问题:ESLint 9.0.0升级后出现ConfigError:无法重定义@typescript-eslint插件

执行bun lint时触发如下错误:

⋊> ~/A/fusion on turborepo ⨯ bun lint                                                          22:21:58
$ eslint packages/*/src/**/*

Oops! Something went wrong! :(

ESLint: 9.0.0

ConfigError: Config (unnamed): Key "plugins": Cannot redefine plugin "@typescript-eslint".
    at rethrowConfigError (/Users/aleksandrkireev/Apps/fusion/node_modules/@humanwhocodes/config-array/api.js:225:8)
    at /Users/aleksandrkireev/Apps/fusion/node_modules/@humanwhocodes/config-array/api.js:1018:5
    at Array.reduce (<anonymous>)
    at FlatConfigArray.getConfig (/Users/aleksandrkireev/Apps/fusion/node_modules/@humanwhocodes/config-array/api.js:1014:39)
    at FlatConfigArray.isFileIgnored (/Users/aleksandrkireev/Apps/fusion/node_modules/@humanwhocodes/config-array/api.js:1046:15)
    at /Users/aleksandrkireev/Apps/fusion/node_modules/eslint/lib/eslint/eslint-helpers.js:514:38
    at Array.forEach (<anonymous>)
    at findFiles (/Users/aleksandrkireev/Apps/fusion/node_modules/eslint/lib/eslint/eslint-helpers.js:503:11)
    at async ESLint.lintFiles (/Users/aleksandrkireev/Apps/fusion/node_modules/eslint/lib/eslint/eslint.js:846:27)
    at async Object.execute (/Users/aleksandrkireev/Apps/fusion/node_modules/eslint/lib/cli.js:461:23)
⋊> ~/A/fusion on turborepo ⨯             

项目依赖:

"dependencies": {
    "alor-api": "1.0.47",
    "axios": "1.6.8",
    "cache-manager": "5.5.1",
    "core-js": "3.36.1",
    "create-hmac": "1.1.7",
    "crypto-hash": "3.0.0",
    "date-fns": "^2.28.0",
    "eslint-plugin-react-hooks": "4.6.0",
    "moment": "2.30.1",
    "msgpack5": "6.0.2",
    "node-cron": "3.0.3",
    "node-fetch": "3.3.2",
    "node-yaml-config": "1.0.0",
    "react": "18.2.0",
    "react-dom": "18.2.0",
    "react-error-overlay": "6.0.11",
    "reflect-metadata": "0.2.2",
    "regenerator-runtime": "0.14.1",
    "request": "2.88.2",
    "swr": "2.2.5",
    "tslib": "2.6.2",
    "winston": "^3.8.2",
    "winston-daily-rotate-file": "^4.7.1",
    "winston-loki": "^6.0.6",
    "winston-telegram": "^2.6.0"
  },
  "devDependencies": {
    "@testing-library/react": "14.3.0",
    "@types/bun": "^1.0.12",
    "@types/jest": "29.5.12",
    "@types/node": "20.12.5",
    "@types/node-fetch": "^2.6.11",
    "@types/react": "18.2.74",
    "@types/react-dom": "18.2.24",
    "@typescript-eslint/parser": "^7.5.0",
    "babel-jest": "29.7.0",
    "create-ts-index": "^1.14.0",
    "cypress": "13.7.2",
    "esbuild": "^0.20.2",
    "eslint": "^9.0.0",
    "eslint-config-next": "^14.1.4",
    "eslint-config-prettier": "^9.1.0",
    "eslint-config-standard-with-typescript": "^43.0.1",
    "eslint-plugin-cypress": "^2.10.3",
    "eslint-plugin-import": "^2.25.2",
    "eslint-plugin-jsx-a11y": "^6.8.0",
    "eslint-plugin-n": "^15.0.0 || ^16.0.0",
    "eslint-plugin-promise": "^6.0.0",
    "eslint-plugin-react": "^7.34.1",
    "eslint-plugin-unused-imports": "^3.1.0",
    "globals": "^15.0.0",
    "husky": "^9.0.11",
    "jest": "29.4.3",
    "jest-environment-jsdom": "29.4.3",
    "jest-environment-node": "^29.4.1",
    "lint-staged": "^13.1.0",
    "sass": "1.74.1",
    "ts-jest": "29.1.2",
    "ts-node": "^10.9.2",
    "tsconfig-paths": "^4.2.0",
    "typescript": "^5.4.4",
    "typescript-eslint": "^7.5.0",
    "url-loader": "^4.1.1"
  }

当前eslint.config.js配置:

import globals from "globals";
import tseslint from "typescript-eslint";
import pluginReactConfig from "eslint-plugin-react/configs/recommended.js";

import path from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
import pluginJs from "@eslint/js";

// mimic CommonJS variables -- not needed if using CommonJS
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({baseDirectory: __dirname, recommendedConfig: pluginJs.configs.recommended});

export default [
  {languageOptions: { globals: globals.browser }},
  ...compat.extends("standard-with-typescript"),
  ...tseslint.configs.recommendedTypeChecked,
  {
    languageOptions: {
      parserOptions: {
        project: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },
  pluginReactConfig,
];

解决方法

错误核心是配置中重复注册了@typescript-eslint插件:

  • compat.extends("standard-with-typescript") 已经包含完整的TypeScript ESLint配置,包括插件注册和基础规则
  • ...tseslint.configs.recommendedTypeChecked 同样会注册@typescript-eslint插件,ESLint 9.0.0的扁平配置机制会检测到重复定义并抛出错误

方案1:移除重复的配置引入

保留standard-with-typescript配置(它已包含TypeScript类型检查相关规则),移除...tseslint.configs.recommendedTypeChecked,修改后的配置如下:

import globals from "globals";
import pluginReactConfig from "eslint-plugin-react/configs/recommended.js";

import path from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
import pluginJs from "@eslint/js";

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

export default [
  {languageOptions: { globals: globals.browser }},
  ...compat.extends("standard-with-typescript"),
  {
    languageOptions: {
      parserOptions: {
        project: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },
  pluginReactConfig,
];

方案2:合并规则而非重复引入配置

如果需要在standard-with-typescript基础上补充recommendedTypeChecked的规则,可以手动提取规则并合并,避免重复注册插件:

import globals from "globals";
import tseslint from "typescript-eslint";
import pluginReactConfig from "eslint-plugin-react/configs/recommended.js";

import path from "path";
import { fileURLToPath } from "url";
import { FlatCompat } from "@eslint/eslintrc";
import pluginJs from "@eslint/js";

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

// 提取recommendedTypeChecked的规则部分,排除插件注册
const typeCheckedRules = tseslint.configs.recommendedTypeChecked.map(config => ({
  ...config,
  plugins: undefined, // 移除插件注册部分
}));

export default [
  {languageOptions: { globals: globals.browser }},
  ...compat.extends("standard-with-typescript"),
  ...typeCheckedRules,
  {
    languageOptions: {
      parserOptions: {
        project: true,
        tsconfigRootDir: import.meta.dirname,
      },
    },
  },
  pluginReactConfig,
];

额外检查

确保typescript-eslint和@typescript-eslint/parser版本一致(当前均为7.5.0,无问题),避免版本冲突引发其他异常。


内容的提问来源于stack exchange,提问作者Alexander Kireyev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 04:45:05