Angular 6 转SSR时出现No NgModule metadata found错误求助
这个错误通常是Angular编译器无法正确识别你的NgModule元数据导致的,结合你的代码和SSR场景,我整理了几个最可能的修复方向:
1. 修复AppModule中Providers的数组嵌套问题
看你的AppModule代码,PROVIDERS数组里直接放入了interceptors变量——但interceptors本身就是一个数组,这会导致PROVIDERS变成数组嵌套的结构([..., [...], ...]),Angular无法正确解析这种格式的provider,进而导致模块元数据识别失败。
修改PROVIDERS定义,用扩展运算符展开interceptors数组:
const PROVIDERS = [ AppResources, AppServices, ...interceptors, // 这里用...展开数组,替换原来的interceptors Location, AppLoadService, { provide: APP_INITIALIZER, useFactory: init_app, deps: [AppLoadService], multi: true }, ];
2. 确保AppServerModule正确配置(SSR必备)
Angular SSR需要单独的AppServerModule来处理服务器端渲染逻辑,如果你还没创建这个模块,或者配置有误,也会触发这个错误:
在src/main.server.ts中创建并导出AppServerModule:
import { NgModule } from '@angular/core'; import { ServerModule } from '@angular/platform-server'; import { AppModule } from './app.module'; import { AppComponent } from './app.component'; @NgModule({ imports: [ AppModule, // 导入你的主AppModule ServerModule, // 服务器端渲染核心模块 ], bootstrap: [AppComponent], }) export class AppServerModule {}
3. 验证server.ts中的bootstrap配置
确保你的server.ts(SSR的Express服务器入口)中,ngExpressEngine的bootstrap参数指向的是AppServerModule类,而不是实例或者AppModule:
import { AppServerModule } from './src/main.server'; // ...其他导入 app.engine('html', ngExpressEngine({ bootstrap: AppServerModule, // 注意这里是类,不要写成new AppServerModule()或者AppModule }));
4. 检查APP_INITIALIZER的服务器端兼容性
你的APP_INITIALIZER依赖AppLoadService的load方法,如果这个方法里调用了浏览器专属API(比如window、document),在服务器端渲染时会出错,进而影响模块解析。
在AppLoadService的load方法中添加平台判断:
import { Inject, PLATFORM_ID } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; // ... constructor(@Inject(PLATFORM_ID) private platformId: Object) {} load() { if (isPlatformBrowser(this.platformId)) { // 只在浏览器环境执行依赖浏览器API的逻辑 // 比如读取localStorage、操作DOM等 } // 服务器端可以执行的逻辑(比如请求API获取配置) return Promise.resolve(); }
完成以上修改后,重新执行npm run build:ssr && npm run serve:ssr,应该就能解决这个错误了。
内容的提问来源于stack exchange,提问作者frostme

