如何在tsconfig中排除node_modules/@types/**/node_modules?(适配awesome-typescript-loader)
解决嵌套@types依赖与顶层@types的冲突问题
我来分享几个针对你这个场景的可行方案,毕竟我也碰到过类似的嵌套类型定义冲突,尤其是在用awesome-typescript-loader的时候限制确实挺多的:
一、核心问题复盘
你遇到的是node_modules/@types下的嵌套依赖版本冲突,结构如下:
@types |-angular //v1.5 |-angular-ui-bootstrap |-node_modules |-@types |-angular //v1.6
顶层的angular@1.5类型和angular-ui-bootstrap嵌套安装的angular@1.6类型定义产生冲突,且你尝试的exclude、types、typeRoots方法都因为TypeScript或loader的限制没达到预期效果。
二、适配awesome-typescript-loader的可行解决方案
方案1:用paths强制映射到顶层类型
在tsconfig.json的compilerOptions里配置paths,直接告诉TypeScript不管哪里引用angular类型,都指向你顶层安装的v1.5版本,绕开嵌套依赖的干扰:
{ "compilerOptions": { "baseUrl": ".", "paths": { "@angular/*": ["../node_modules/@types/angular/*"] } } }
方案2:锁定依赖版本避免嵌套安装
通过包管理器的版本锁定功能,强制所有依赖的@types/angular都使用你需要的1.5版本,从根源上避免嵌套安装:
- 如果你用Yarn,在
package.json中添加:
"resolutions": { "@types/angular": "1.5.x" }
- 如果你用npm(版本≥8.3),在
package.json中添加:
"overrides": { "@types/angular": "1.5.x" }
配置完重新执行npm install或yarn install,就不会再出现嵌套的angular@1.6类型了。
方案3:调整loader配置,严格遵循types列表
在webpack配置里给awesome-typescript-loader加上专属配置,配合tsconfig的types设置,强制只引入你指定的顶层类型:
webpack配置片段:
module.exports = { module: { rules: [ { test: /\.ts$/, loader: 'awesome-typescript-loader', options: { useWebpackText: true, forceIsolatedModules: true } } ] } }
同时保持tsconfig.json里的types配置:
{ "compilerOptions": { "types": ["angular", "angular-ui-bootstrap"] } }
这个配置会让loader更严格地遵循tsconfig的类型列表,不会自动引入依赖包里的嵌套类型。
三、为什么你之前的方法没起作用?
结合你的结论补充下深层原因:
exclude对@types无效:TypeScript默认会自动扫描@types目录下的所有类型,exclude不会覆盖这个默认行为,除非配合typeRoots或types配置。types引入会带依赖:TypeScript的types配置会自动引入指定类型的依赖类型,所以angular-ui-bootstrap依赖的angular还是会被拉进来。typeRoots不支持复杂通配符:TypeScript的typeRoots只支持简单的目录匹配,../node_modules/@types/**/!(node_modules)这种否定式通配符确实不被支持。
环境详情:
- node: 8.6.0
- typescript: 2.8.3
- awesome-typescript-loader: 5.0.0
- webpack: 4.8.3
内容的提问来源于stack exchange,提问作者user2954463
相关产品推荐
相关产品推荐

