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

如何修复ESLint无法唯一确定@typescript-eslint插件的错误?

解决ASP.NET Core MVC + React+TypeScript项目中ESLint "@typescript-eslint" 重复加载错误

问题背景

在Visual Studio 2022社区版17.6.3中,基于“ASP.NET Core with React.js”模板创建的项目(ClientApp目录由create-react-app生成),启用ESLint代码检查时,始终遇到以下错误:

yarn run v1.22.19
$ eslint ./src/

Oops! Something went wrong! :(

ESLint: 8.48.0

ESLint couldn't determine the plugin "@typescript-eslint" uniquely.

  • C:\path\to\MyProject\ClientApp\node_modules@typescript-eslint\eslint-plugin\dist\index.js (loaded in "src.eslintrc.json")
  • C:\path\to\MyProject\ClientApp\node_modules\eslint-config-react-app\node_modules@typescript-eslint\eslint-plugin\dist\index.js (loaded in "src.eslintrc.json » eslint-config-react-app#overrides[0]")

Please remove the "plugins" setting from either config or remove either plugin installation.

推测错误源于项目不同依赖路径下存在多个版本的@typescript-eslint,但对错误信息中“src.eslintrc.json » eslint-config-react-app#overrides[0]”的含义感到困惑——自身的.eslintrc.json中并没有相关配置。

已尝试以下方案但未解决:

  • 使用与文件系统一致的大小写路径访问项目
  • 手动保存package.json修改
  • 执行dedupe命令
  • 删除node_modules、package-lock.json/yarn.lock后重新安装依赖
  • 分别用npm和yarn尝试上述操作,切换时删除对应锁文件

项目配置文件

package.json

{  
  "name": "myapp",  
  "version": "0.1.0",  
  "private": true,  
  "dependencies": {    
    "bootstrap": "^5.3.1",    
    "http-proxy-middleware": "^2.0.6",    
    "jquery": "^3.7.0",    
    "merge": "^2.1.1",    
    "oidc-client": "^1.11.5",    
    "react": "^18.2.0",    
    "react-bootstrap": "^2.8.0",    
    "react-dom": "^18.2.0",    
    "react-in-viewport": "^1.0.0-alpha.30",    
    "react-router-bootstrap": "^0.26.2",    
    "react-router-dom": "^6.15.0",    
    "reactstrap": "^9.2.0",    
    "rimraf": "^5.0.1",    
    "web-vitals": "^3.4.0"  
  },  
  "devDependencies": {    
    "@babel/eslint-parser": "^7.22.11",    
    "@babel/plugin-proposal-private-property-in-object": "^7.21.11",    
    "@types/jest": "^29.5.4",    
    "@types/react": "^18.2.21",    
    "@typescript-eslint/eslint-plugin": "^6.4.1",    
    "@typescript-eslint/parser": "^6.4.1",    
    "ajv": "^8.12.0",    
    "cross-env": "^7.0.3",    
    "eslint": "^8.48.0",    
    "eslint-plugin-flowtype": "^8.0.3",    
    "eslint-plugin-import": "^2.28.1",    
    "eslint-plugin-jest": "^27.2.3",    
    "eslint-plugin-jest-formatting": "^3.1.0",    
    "eslint-plugin-jsdoc": "^46.5.0",    
    "eslint-plugin-jsx-a11y": "^6.7.1",    
    "eslint-plugin-react": "^7.33.2",    
    "nan": "^2.17.0",    
    "react-scripts": "^5.0.1",    
    "typescript": "4.3.5"  
  },  
  "jest": {    
    "coveragePathIgnorePatterns": [      
      "/src/index.js",      
      "/src/reportWebVitals.js",      
      "/src/service-worker.js",      
      "/src/serviceWorkerRegistration.js",      
      "/src/setupProxy.js",      
      "/src/components/",      
      "/src/Models"    
    ],    
    "coverageReporters": [      
      "json",      
      "html",      
      "text"    
    ]  
  },  
  "overrides": {    
    "autoprefixer": "10.4.5",    
    "semver": "^7.5.2",    
    "svgo": "^2.0.0"  
  },  
  "resolutions": {    
    "css-what": "^5.0.1",    
    "nth-check": "^2.0.0"  
  },  
  "scripts": {    
    "prestart": "node aspnetcore-https && node aspnetcore-react",    
    "start": "rimraf ./build && react-scripts start",    
    "build": "react-scripts build",    
    "test": "cross-env CI=true react-scripts test --env=jsdom",    
    "watch": "cross-env CI=true react-scripts test --env=jsdom --watchAll --coverage",    
    "eject": "react-scripts eject",    
    "lint": "eslint ./src/"  
  },  
  "browserslist": {    
    "production": [      
      ">0.2%",      
      "not dead",      
      "not op_mini all"    
    ],    
    "development": [      
      "last 1 chrome version",      
      "last 1 firefox version",      
      "last 1 safari version"    
    ]  
  },  
  "peerDependencies": {    
    "@babel/core": "^7.11.0",    
    "@babel/plugin-syntax-flow": "^7.14.5",    
    "@babel/plugin-transform-react-jsx": "^7.14.9",    
    "@popperjs/core": "^2.11.8"  
  }
}

.eslintrc.json

{  
  "parser": "@typescript-eslint/parser",  
  "extends": [    
    "eslint:recommended",    
    "plugin:import/errors",    
    "plugin:import/warnings",    
    "plugin:react/recommended",    
    "plugin:jsdoc/recommended",    
    "react-app"  
  ],  
  "env": {    
    "browser": true,    
    "node": true,    
    "mocha": true,    
    "es6": true,    
    "jest": true  
  },  
  "overrides": [    
    {      
      "files": [        
        "**/*.test.js"      
      ],      
      "env": {        
        "jest": true      
      },      
      "plugins": [        
        "jest",        
        "jest-formatting"      
      ],      
      "rules": {        
        // Omitted for brevity, I can edit them back in if needed      
      }    
    }  
  ],  
  "plugins": [    
    "react",    
    "import",    
    "jsx-a11y",    
    "jest",    
    "jsdoc",    
    "@typescript-eslint"  
  ],  
  "parserOptions": {    
    "ecmaVersion": 6,    
    "sourceType": "module",    
    "ecmaFeatures": {      
      "jsx": true    
    }  
  },  
  "rules": {    
    // Omitted for brevity, I can edit them back in if needed  
  },  
  "settings": {    
    "react": {      
      "version": "18"    
    },    
    "import/resolver": {      
      "node": {        
        "extensions": [ ".js", ".jsx", ".ts", ".tsx" ]      
      }    
    }  
  }
}

tsconfig.json

{  
  "compilerOptions": {    
    "target": "ES6",    
    "lib": ["es6", "DOM"],    
    "jsx": "react",    
    "module": "commonjs",    
    "moduleResolution": "node",    
    "types": ["jest", "node", "@types/jest"],    
    "esModuleInterop": true,    
    "forceConsistentCasingInFileNames": true,    
    "strict": true,    
    "noImplicitAny": true,    
    "strictNullChecks": true,    
    "skipDefaultLibCheck": true,    
    "skipLibCheck": true  
  }
}

解决方案

核心原因

错误信息里的“src.eslintrc.json » eslint-config-react-app#overrides[0]”意思是:你自己的.eslintrc.json继承了react-app配置,而react-app内部的overrides[0]配置也加载了@typescript-eslint插件,加上你自己在plugins数组里手动声明了@typescript-eslint,导致ESLint加载了两个不同路径下的插件实例(一个是你直接安装的顶级node_modules,一个是eslint-config-react-app依赖的嵌套node_modules)。

修复步骤

  1. 从你的.eslintrc.json中移除@typescript-eslint插件声明
    打开.eslintrc.json,找到plugins数组,删除其中的"@typescript-eslint"项。因为react-app配置已经包含了该插件的加载,不需要重复声明。修改后的plugins数组应该是:

    "plugins": [
      "react",
      "import",
      "jsx-a11y",
      "jest",
      "jsdoc"
    ]
    
  2. 锁定@typescript-eslint版本与react-app依赖的版本一致(可选但推荐)
    先执行yarn list @typescript-eslint/eslint-plugin查看eslint-config-react-app依赖的嵌套版本,然后在package.json的resolutions(yarn)或overrides(npm)中添加配置强制统一版本:

    "resolutions": {
      "@typescript-eslint/eslint-plugin": "^5.62.0",
      "@typescript-eslint/parser": "^5.62.0",
      "css-what": "^5.0.1",
      "nth-check": "^2.0.0"
    }
    
  3. 重新安装依赖
    删除node_modules和yarn.lock(或package-lock.json),然后执行yarn install(或npm install)。

  4. 验证修复
    运行yarn lint,错误应该消失。

补充说明

  • 不需要手动声明@typescript-eslint插件的原因是,react-app配置已经集成了TypeScript相关的ESLint配置,包括插件和解析器的加载。
  • 如果后续需要自定义@typescript-eslint的规则,直接在.eslintrc.json的rules数组中添加即可,无需重复声明插件。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 02:07:34