首页 > 解决方案 > Angular 6 - 使用 AOT 编译在运行时动态创建模块

问题描述

我正在尝试动态加载创建模块并将它们添加到通过loadChildren. 这种方法的主要原因是路由配置应该从json文件中加载。

所以我有canActivate负责创建模块的警卫

loadFeatureModule(loadChildren: string): Observable<Type<any>> {

  this.getRoutes(loadChildren).pipe(
    switchMap(({ routes }) => {
      const featureModule = NgModule({
        imports: [
          RouterModule.forChild(routes)
        ]
      })(class { });
      return this.compiler.compileModuleAsync(featureModule);
    }),
    map(m => m.moduleType)
  );
}

并将功能模块添加到路线:

addFeatureModule = (loadChildren: string, path: string): Partial<Route> => {
  return {
    path: path,
    loadChildren: this.loadFeatureModule(loadChildren)
  };
}

最后,我用新路由重置了路由器配置。这适用于 JIT 编译器,但它不会使用 AOT 编译器加载任何路由。

我还尝试通过引入这些新提供程序将 JitComplier 注入应用程序:

providers: [
  { provide: COMPILER_OPTIONS, useValue: {}, multi: true },
  { provide: CompilerFactory, useClass: JitCompilerFactory, deps: [COMPILER_OPTIONS] },
  { provide: Compiler, useFactory: createCompiler, deps: [CompilerFactory] }
]

export function createCompiler(compilerFactory: CompilerFactory) {
  return compilerFactory.createCompiler();
}

更新

请使用此repo重现问题

问题

经过进一步调查,我发现了两个问题:

  1. AOT并删除编译动态模块所需buildOptimizer的角度装饰器NgModuleComponent显然没有解决方案buildOptimizer,我发现了这个讨厌的黑客AOT但是有更好的解决方案吗?

  2. 动态创建模块templateUrl时,无法加载在动态模块中直接/间接声明的任何组件。在我的示例中,这意味着我无法导入LayoutModule到动态模块中,因为它声明了一个使用.templateUrlResourceLoaderAOT

标签: angular

解决方案


推荐阅读