使用ng-packagr发布的包安装后报错:NgZone无提供者
我之前也碰到过一模一样的问题!这种NullInjectorError: No provider for NgZone!的报错,大多是因为库的打包配置或者模块设置没处理好,尤其是你用指令替代组件的场景,很容易忽略一些Angular核心依赖的细节。
几个大概率能解决问题的方向:
检查库模块的配置
先看看你的指令所属的模块,是不是不小心在providers数组里手动添加了NgZone?NgZone是Angular核心自动提供的服务,根本不需要我们手动声明提供者,要是加了反而会和消费应用的Angular环境冲突,导致找不到正确的实例。确认peerDependencies配置
用ng-packagr打包库的话,一定要把@angular/core、@angular/common这些核心包放在package.json的peerDependencies里,而不是dependencies。这样消费应用会用自己项目里的Angular核心依赖,不会出现重复打包或者依赖缺失的情况。
给你个参考配置:"peerDependencies": { "@angular/core": "^14.0.0", "@angular/common": "^14.0.0" }注意版本号要和你开发库时用的Angular版本匹配,也可以用范围版本比如
^14.x.x来兼容同大版本的项目。排查指令的实现代码
看看你的指令构造函数里是不是注入了NgZone?虽然正常注入是没问题的,但如果你的指令里有一些脱离Angular Zone的操作,或者错误地尝试自己创建NgZone实例,也可能触发这个错误。不过这种情况比较少见,先优先检查前面的配置问题。清理缓存重新打包发布
有时候本地打包的缓存会搞事情,删掉库的dist文件夹,重新跑ng build或者ng-packagr的打包命令,然后重新发布到npm(或者本地用npm link测试),再在消费应用里重新安装一遍,很多时候缓存导致的奇怪问题就这么解决了。
额外的排查小技巧:
如果上面的方法都没用,再检查下消费应用:
- 确保消费应用的Angular版本和你库的
peerDependencies版本兼容,跨大版本的话很容易出现依赖注入的问题; - 看看
app.module.ts里是不是重复导入了你的库模块,或者和其他第三方模块有依赖冲突。
附你遇到的错误信息:
Error: StaticInjectorError(AppModule)[ApplicationRef -> NgZone]: StaticInjectorError(Platform: core)[ApplicationRef -> NgZone]: NullInjectorError: No provider for NgZone! at NullInjector.get (VM1509 core.umd.js:1063) at resolveToken (VM1509 core.umd.js:1316) at tryResolveToken (VM1509 core.umd.js:1266) at StaticInjector.get (VM1509 core.umd.js:1161) at resolveToken (VM1509 core.umd.js:1316) at tryResolveToken (VM1509 core.umd.js:1266) at StaticInjector.get (VM1509 core.umd.js:1161) at resolveNgModuleDep (VM1509 core.umd.js:9322) at _createClass (VM1509 core.umd.js:9367) at _createProviderInstance$1 (VM1509 core.umd.js:9339) console.(anonymous function) @ preview-45b825bb367532ab5b87a.js:1 (anonymous) @ main.ts:26 ZoneDelegate.invoke @ zone.js:388 Zone.run @ zone.js:138 (anonymous) @ zone.js:872 ZoneDelegate.invokeTask @ zone.js:421 Zone.runTask @ zone.js:188 drainMicroTaskQueue @ zone.js:595 Promise.then (async) scheduleMicroTask @ zone.js:578 ZoneDelegate.scheduleTask @ zone.js:410 Zone.scheduleTask @ zone.js:232 Zone.scheduleMicroTask @ zone.js:252 scheduleResolveOrReject @ zone.js:862 ZoneAwarePromise.then @ zone.js:962 PlatformRef.bootstrapModule @ application_ref.ts:275 execute @ main.ts:19
内容的提问来源于stack exchange,提问作者Black Mamba

