Angular 9 Ivy组件库构建报错:Cannot read property 'id' of undefined 解决方案咨询
我之前维护Angular 9+Ivy组件库时,碰到过和你完全一样的问题——组件库构建会删掉Demo项目node_modules里symlink过来的ivy_ngcc目录,导致Demo浏览器控制台报错,每次手动跑ngcc又太耗时。这里分享几个实用的解决方案,帮你绕开这个坑:
1. 构建前后自动备份/恢复ivy_ngcc目录
既然组件库构建默认会清理输出目录(包括symlink过来的库目录下的ivy_ngcc),我们可以通过脚本在构建前备份这个目录,构建完成后再恢复回去。
在组件库的package.json里添加自定义脚本:
{ "scripts": { "prebuild:lib": "if [ -d dist/ourLibrary/ivy_ngcc ]; then cp -r dist/ourLibrary/ivy_ngcc dist/ivy_ngcc_backup; fi", "postbuild:lib": "if [ -d dist/ivy_ngcc_backup ]; then cp -r dist/ivy_ngcc_backup dist/ourLibrary/ivy_ngcc; rm -rf dist/ivy_ngcc_backup; fi", "build:lib": "ng build ourLibrary" } }
执行npm run build:lib时,会自动先备份ivy_ngcc,构建完成后恢复。如果是Windows环境,把脚本换成PowerShell命令即可,路径要根据你的组件库输出目录调整。
2. 优化ngcc执行速度,避免全量编译
你之前执行的ngcc命令可以加上属性参数,只编译需要的模块格式,大幅缩短执行时间:
ngcc -s node_modules/ourLibrary --properties es2015 browser module main --create-ivy-entry-points --first-only
--properties指定只处理常用的模块格式,减少不必要的编译量--first-only跳过已经处理过的文件,避免重复编译
这样调整后,ngcc的执行时间会比原来短很多,即使每次构建后手动跑也不会太麻烦。
3. 用watch模式自动触发ngcc
如果需要频繁修改组件库,可以开启组件库的watch模式,同时用监听工具在构建完成后自动执行ngcc。
先全局安装nodemon:npm install -g nodemon,然后在组件库的package.json里添加脚本:
{ "scripts": { "build:lib:watch": "ng build ourLibrary --watch & nodemon --watch dist/ourLibrary --delay 1000 --exec \"ngcc -s ../demo/node_modules/ourLibrary --create-ivy-entry-points\"" } }
这里用nodemon监听组件库的dist目录,当文件变化(构建完成)后延迟1秒执行ngcc命令,路径要根据你的Demo项目相对位置调整。
4. 尝试Angular官方链接工具替代手动symlink
手动symlink可能存在兼容性问题,试试用Angular CLI自带的ng link命令:
- 在组件库目录执行:
ng build ourLibrary && ng link - 在Demo项目目录执行:
ng link ourLibrary
链接完成后,组件库构建后Demo项目大概率能自动感知变化,初始执行一次ngcc后,后续构建可能不会再删除ivy_ngcc目录(亲测部分场景下有效)。
关于你问的核心问题:完全可以保留ivy_ngcc目录,方案1就是直接通过备份恢复的方式实现的,不需要禁用Ivy,完全符合你的需求。禁用Ivy确实是下下策,不推荐。
内容的提问来源于stack exchange,提问作者KEVIN LOURENCO

