Angular CLI 6:如何在主应用中使用库子项目?
首先,我们来拆解你遇到的两个核心问题:模块找不到的错误,以及Angular 6/ng-packagr对子路径导入(tree-shakeable)的支持性。
一、解决"Module not found"错误
你遇到的模块找不到问题,大概率是路径配置或者库构建的细节没处理到位,按以下步骤排查:
确保库已正确构建
先执行库的构建命令:ng build my-package构建完成后,确认
dist/my-package/button目录下存在完整的文件(比如button.module.ts、对应的.d.ts类型文件,以及index.ts入口文件——如果你的子模块是通过index导出的话)。修正tsconfig.json的paths配置
你的paths配置只覆盖了子路径,但可能缺少主包的映射,同时要确保baseUrl设置正确。修改后的tsconfig.json应该类似:{ "compilerOptions": { "baseUrl": "./", "paths": { "@my-company/my-package": ["dist/my-package"], "@my-company/my-package/*": ["dist/my-package/*"] } } }这样既映射了主包,也覆盖了所有子路径。
让Angular CLI正确识别本地库路径
Angular CLI默认会优先从node_modules查找依赖,直接用dist路径可能会有解析问题。可以通过npm link把本地库链接到主应用的node_modules:# 进入库的dist目录 cd dist/my-package # 执行链接 npm link # 回到主应用目录,链接该库 cd ../../ npm link @my-company/my-package之后你就可以像导入第三方库一样使用子路径,CLI会正确解析。
二、Angular 6/ng-packagr对子路径导入(tree-shakeable)的支持性
Angular 6搭配的ng-packagr版本(通常是v3.x)是支持子路径导入以实现tree-shaking的,但需要你的库结构满足以下要求:
- 每个子模块(比如
button)都有独立的入口文件(比如button/index.ts),并且在该文件中导出模块的核心内容(比如ButtonModule)。 - 库的主
package.json不需要额外配置exports(这个是Node.js ESM的特性,Angular 6时期还不依赖这个),只要dist目录的结构和你的子路径导入对应即可。 - 确保你的库是用ng-packagr构建的(Angular 6的库默认就是用它),它会生成符合Angular CLI解析要求的tree-shakeable模块结构。
当你用子路径导入时,Angular的构建工具(webpack + rollup)会只打包你导入的子模块代码,不会引入整个库的冗余内容,实现tree-shaking的效果。
如果还是有问题,可以检查库的ng-package.json配置,确保没有禁用tree-shaking相关的选项(默认是开启的)。
内容的提问来源于stack exchange,提问作者Joe Attardi

