Angular13应用加载时报runOutsideAngular未定义TypeError求助
问题根因
报错TypeError: Cannot read properties of undefined (reading 'runOutsideAngular')的触发逻辑是:ApmService 内部依赖 Angular 的 NgZone 实例调用runOutsideAngular方法规避变更检测损耗,但当前代码中拿到的ApmService实例没有完成依赖注入,内部持有的NgZone值为undefined,最终触发类型错误。
这个问题和tsconfig里的target编译版本配置无关,常见触发场景有三个:
- 未在AppModule的imports中正确导入
ApmModule并通过forRoot()注册,直接在构造器中通过@Inject()拿服务,得到的是未完成依赖初始化的无效实例 - 安装的
@elastic/apm-rum-angular版本与Angular 13不兼容:Angular 13 仅兼容 3.x 版本的@elastic/apm-rum-angular,如果安装了2.x及更早版本,内部依赖注入逻辑适配的是Angular旧版本规则,在Angular13环境下无法正确获取NgZone实例 - 时序逻辑错误:给service.init套了1s的setTimeout,会让初始化逻辑脱离Angular的模块生命周期执行,进一步放大依赖缺失的问题
修复步骤
- 先修正依赖版本,执行以下命令安装Angular13兼容的APM包:
npm uninstall @elastic/apm-rum-angular @elastic/apm-rum npm install @elastic/apm-rum-angular@3.0.1
- 重构AppModule代码,移除手动调用service.init的逻辑和setTimeout包裹,通过框架标准的
ApmModule.forRoot()传入APM配置,由模块负责完成服务初始化和依赖注入:
import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { ApmModule, ApmService } from '@elastic/apm-rum-angular'; import { environment } from './environments/environment'; import { AppComponent } from './app.component'; @NgModule({ declarations: [AppComponent], imports: [ BrowserModule, ApmModule.forRoot({ active: environment.elasticApmActive, environment: environment.production ? 'prod' : 'qa', serviceName: environment.appName, serverUrl: environment.elasticServerUrl }) ], providers: [], bootstrap: [AppComponent] }) export class AppModule { // 如需获取apm实例做自定义上报,直接注入服务即可,无需手动调用init constructor(private apmService: ApmService) { const apm = this.apmService.apm; // 自定义APM逻辑可在此编写 } }
- 修正tsconfig.json的types配置,当前配置仅加载jasmine类型声明,会导致Node环境和其他依赖的类型声明无法被正确加载,修改为:
"types": ["jasmine", "node"]
验证
修改完成后重启本地开发服务,强制刷新浏览器清空缓存,之前的runOutsideAngular报错会消失,APM agent可正常完成初始化和数据上报。
注意:Angular服务的初始化不要随意用setTimeout延迟脱离框架生命周期执行,否则会跳过框架内置的依赖校验和初始化时序控制,极易出现各类偶发的undefined报错。
内容的提问来源于stack exchange,提问作者Maliha Khizer
相关产品推荐
相关产品推荐

