如何解决ESLint报错:包应列入dependencies而非devDependencies
在React+TypeScript项目中用ESLint做规范校验时,业务组件引入react-router的useParams钩子:
import { useParams } from 'react-router';
ESLint抛出import/no-extraneous-dependencies规则报错,提示@types/react-router应该放在dependencies而非devDependencies中。
1. 为什么该规则提示@types/react-router需要列入dependencies而非devDependencies?
import/no-extraneous-dependencies规则的默认校验逻辑非常直白:只要业务运行时代码中关联到了某一个依赖包,就判定该包属于生产依赖,应该放在dependencies中。
这个规则本身没有内置TypeScript类型包的识别能力,当你在TS文件中导入react-router的API时,TS会自动读取@types/react-router下的类型声明做类型校验,ESLint扫描到源码和@types/react-router存在关联,就会触发默认校验逻辑抛出报错,本质是规则没有区分「运行时依赖」和「仅编译时用的类型依赖」导致的误报。
2. 我是否真的需要将@types/react-router移至dependencies配置项?
完全不需要。
所有@types/*开头的包都是TypeScript类型声明包,仅在TS编译做类型检查阶段会被读取,不会被打包进最终的生产环境产物,浏览器运行时完全不会用到这些包,这类包天生就应该归类为开发依赖,放在devDependencies中。
额外说明:react-router v6及以上版本已经内置了TS类型声明,根本不需要单独安装@types/react-router包,如果你的项目用的是v6+版本,可以直接把这个多余的类型包卸载掉。
3. 我是否可以直接禁用该规则?如何判断ESLint规则什么时候可以禁用、什么时候需要修复对应报错?
不建议全局禁用这个规则,只需要给规则添加针对@types/*包的校验例外即可,保留规则对真正运行时依赖的校验能力,避免出现生产环境漏装依赖的问题。
可以在ESLint配置中按如下方式调整规则:
// .eslintrc.js 对应规则配置 rules: { 'import/no-extraneous-dependencies': [ 'error', { // 允许以下路径下的文件引用devDependencies依赖 devDependencies: [ '**/*.test.{ts,tsx,js,jsx}', '**/*.spec.{ts,tsx,js,jsx}', '**/*.config.{ts,js}', '**/*.d.ts' ], // 忽略所有@types开头的类型包校验 ignorePackages: ['@types/*'] } ] }
判断ESLint报错应该修复还是加例外/禁用,可以参考三个标准:
- 先明确规则的设计目的:如果违反规则会直接导致运行时报错、构建失败、团队协作冲突,就必须修复。比如
no-undef报变量未定义、import/no-unresolved报依赖找不到,这类问题不修大概率线上出bug。 - 如果是规则对特定场景的误判,优先加针对性例外,不要全局禁用规则。比如本次遇到的类型包误报问题,只需要把
@types/*加入忽略列表即可,规则本身对运行时依赖的校验能力依然可以保留。 - 如果规则和团队约定的规范完全冲突,且没有可配置的调整空间,再考虑全局禁用,禁用前需要和团队成员对齐共识,不要私自修改全局规则影响其他协作成员。
内容的提问来源于stack exchange,提问作者Max Green

