升级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
相关产品推荐
相关产品推荐

