如何在JIT Angular应用中导入AOT编译的UMD模块?报错解决
这个错误其实很好理解——Angular的JIT编译器需要读取模块的原始元数据(也就是@NgModule装饰器里的信息),但你要导入的这个模块已经是AOT编译完成的UMD包,它的元数据已经被处理成静态代码了,JIT根本认不出来。下面给你几个可行的解决办法:
直接从window对象引用模块
既然这个模块已经挂载在window上了,完全不需要用import语句去导入,直接在NgModule的imports数组里引用window上的实例就行:
@NgModule({ imports: [ CommonModule, (window as any).ThridModule ], bootstrap: [AppComponent] }) export class AppModule {}
这里用(window as any)是为了绕过TypeScript的类型检查,如果你能拿到这个模块的类型定义文件,后续可以优化类型提示。
优化TypeScript类型体验(可选)
不想每次都写(window as any)的话,你可以在项目里新增一个全局类型声明文件(比如src/global.d.ts),扩展window的类型:
declare global { interface Window { ThridModule: import('@angular/core').NgModule; // 如果有更具体的模块类型,替换成对应的类型即可 } } export {};
这样之后你就能直接写window.ThridModule,TypeScript也不会报错了。
确认模块在window上的正确路径
有些UMD模块可能不会直接把ThridModule挂在window根对象下,而是放在一个命名空间里(比如window.ThirdPartyLib.ThridModule)。你可以打开浏览器控制台,直接输入window查看这个模块的具体挂载位置,确保引用的路径是对的。
为什么原来的import方式不行?
你之前用import { ThridModule } from 'thrid-module'的时候,Angular的JIT编译器会试图去查找这个模块的源文件或者未编译的元数据,但这个模块已经是AOT编译好的成品,没有JIT需要的@NgModule元数据信息了,所以编译器才会报错说“找不到@NgModule注解”。
内容的提问来源于stack exchange,提问作者Lon Yang

