Angular 4中*ngComponentOutlet搭配ngModuleFactory生产环境无法正常运行
解决Angular 4中ngComponentOutlet生产环境失效问题
我之前也碰到过类似的情况,Angular生产环境默认开启的AOT编译,会对动态组件的创建和模块配置有更严格的要求,这大概率是你问题的根源。结合你的代码片段,给你几个针对性的解决方案:
1. 确保动态模块正确声明所有依赖
你的动态组件里用到了custom-directive,但如果这个指令没有被正确声明在动态模块里,生产环境AOT编译时会直接忽略它,导致组件无法正常渲染。你需要在创建动态模块的时候,把自定义指令也加入到declarations和exports数组中:
private createDynamicModule(component: Type<any>) { return NgModule({ declarations: [component, CustomDirective], // 必须声明自定义指令 exports: [component], entryComponents: [component] // Angular 4中动态组件需要加入这里 })(class {}); }
2. 处理AOT下的动态组件创建限制
在生产AOT模式下,Angular不允许动态编译模板(比如你用template字符串直接创建组件的方式),如果你是用Compiler来动态编译组件的话,需要调整策略:要么提前把可能用到的组件和指令加入到主模块的entryComponents,要么使用预编译的模块工厂。
如果你的动态组件是完全动态生成的(模板可变),可以尝试切换到JIT模式编译生产包,但这会增加包体积,作为临时方案可以试试:
ng build --prod --aot=false
不过更推荐的是适配AOT的写法,比如提前定义好组件模板的可能变体,或者使用Angular CDK的动态组件工具。
3. 检查ngComponentOutlet的模块工厂传递
你的模板里用到了ngModuleFactory: dynamicModule,注意在生产环境中,模块工厂需要是预编译好的,而不是动态创建的模块类。你需要用Compiler.compileModuleAndAllComponentsSync来获取模块工厂:
public ngOnInit(): void { const template = '<a custom-directive> </a>'; this.dynamicComponent = this.createNewComponent(template); const dynamicModule = this.createDynamicModule(this.dynamicComponent); // 编译模块获取工厂 const moduleFactory = this.compiler.compileModuleAndAllComponentsSync(dynamicModule); this.dynamicModuleFactory = moduleFactory.moduleFactory; }
然后模板里对应修改:
<ng-container *ngComponentOutlet="dynamicComponent; ngModuleFactory: dynamicModuleFactory;"></ng-container>
别忘了在组件的构造函数中注入Compiler:
constructor(private compiler: Compiler) {}
4. 生产环境的额外配置检查
- 确保你的
tsconfig.json中compilerOptions的emitDecoratorMetadata和experimentalDecorators都设为true,虽然生产AOT可能不需要,但动态组件创建有时依赖这些配置。 - 检查是否开启了摇树优化(tree-shaking),如果自定义指令被误摇掉,也会导致失效。可以在
angular.json的生产配置中暂时关闭摇树优化测试:
"optimization": { "scripts": false, "styles": false, "fonts": false }
内容的提问来源于stack exchange,提问作者Gbenga Medunoye
相关产品推荐
相关产品推荐

