You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular 18升级至19后protobuf.js导入引发NG0203注入错误求助

解决Angular 19升级后protobuf.js的导入及NG0203错误

问题根源

Angular 19默认强制使用ESM(ECMAScript模块),原有的require导入方式不再支持;同时Angular 19对注入上下文的检测更严格,直接全局导入protobuf.js可能导致其初始化代码在注入上下文未准备好时触发inject()调用,从而抛出NG0203错误。

解决方案

1. 升级protobuf.js到兼容ESM的最新版本

首先确保使用的是支持ESM的protobuf.js版本,执行以下命令升级:

npm install protobufjs@latest

2. 避免全局导入,改用动态导入或初始化器加载

不要在main.ts或模块顶部直接静态导入protobuf.js,而是在需要的服务/组件中动态导入,或通过APP_INITIALIZER在Angular注入上下文就绪后初始化。

方法一:使用APP_INITIALIZER全局初始化

在AppModule中配置初始化器,确保protobuf.js在Angular启动前完成加载:

import { NgModule, APP_INITIALIZER } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';

// 初始化protobuf.js的工厂函数
export function initProtobuf() {
  return async () => {
    const $protobuf = await import('protobufjs/minimal');
    // 可在此添加protobuf的基础配置,比如加载proto文件定义
    // 将实例挂载到window(可选,供全局使用)
    (window as any).$protobuf = $protobuf;
  };
}

@NgModule({
  declarations: [AppComponent],
  imports: [BrowserModule],
  providers: [
    {
      provide: APP_INITIALIZER,
      useFactory: initProtobuf,
      multi: true
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

之后在服务或组件中,可通过window.$protobuf获取实例,或封装成专用服务:

import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class ProtobufService {
  private $protobuf: any;

  constructor() {
    this.$protobuf = (window as any).$protobuf;
  }

  // 封装protobuf的编码/解码方法
  decode(messageType: any, data: Uint8Array) {
    return this.$protobuf.Root.fromJSON(messageType).decode(data);
  }
}

方法二:在组件/服务中动态导入

在需要使用protobuf.js的地方直接动态导入,确保在Angular注入上下文内执行:

import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class DataProcessingService {
  async decodeProtoData(rawData: Uint8Array) {
    // 动态导入protobuf.js
    const $protobuf = await import('protobufjs/minimal');
    // 加载proto定义并解码数据
    const protoRoot = $protobuf.Root.fromJSON({
      // 你的proto文件JSON定义
    });
    const TargetMessage = protoRoot.lookupType('your.package.Message');
    return TargetMessage.decode(rawData);
  }
}

3. 排查非法inject()调用

虽然你未修改AppModule,但Angular 19的严格检测可能暴露了之前隐藏的问题:检查项目中所有直接调用inject()的代码,确保它们仅出现在构造函数、工厂函数、管道/指令的构造函数等注入上下文内,禁止在全局作用域、普通函数或无上下文的异步回调中使用inject()。

4. 确认TS配置为ESM模式

检查tsconfig.json中的module字段,确保设置为ESNext或ES2020,避免CommonJS与ESM混合导致的模块加载问题:

{
  "compilerOptions": {
    "module": "ESNext",
    // 其他配置...
  }
}

内容的提问来源于stack exchange,提问作者Felix Gerber

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 16:43:12