我正面临Angular应用程序的问题。
我想用(aot)的Typscript构建一个角度应用程序。
目的是显示带有一些小部件的用户仪表板。小部件是一个角度组件。
我的应用程序附带了一些嵌入式小部件。 但小部件应该通过像市场这样的东西来扩展;或手动创建。
市场应该将文件(js / ts / bunlde .. ??)下载到特定的文件夹中。
然后我的应用程序应该能够加载新的小部件(= ng组件)并实现它们。
我的文件夹结构(制作)
|- index.html
|- main.f5b448e73f5a1f3f796e.bundle.js
|- main.f5b448e73f5a1f3f796e.bundle.js.map
|- .... (all other files generated)
|- externalWidgets
|- widgetA
|- widjetA.js
|- widjetA.js.map
|- assets
|- image.png
|- widgetB
|- widjetB.ts
|- widjetB.html
|- widjetB.css
然后在加载用户页面时,数据库说有一个widgetA。 因此,目标是动态加载文件并实现包含的组件。
我尝试了许多解决方案,使用"要求"和" System.import"但是当动态生成加载路径时,两者都失败了。
这应该可行吗? 我可以改变我的代码结构;更改外部小部件..(例如,widgetB尚未转换,...)
事实上,我正在寻找一个"插件系统"使用Angular4 / webpack应用程序。
答案 0 :(得分:16)
I'm doing exactly the same. And I explain the details in this talk at NgConf.
The first thing to understand is that Webpack cannot dynamically load modules that are unknown during build time. This is inherent to the way Webpack builds dependency tree and collects modules identifiers during build time. And it's perfectly fine since Webpack is a modules bundler, not modules loader. So you need to use a module loader and the only viable option now is SystemJS.
Then, each plugin should be packaged as a module and all exported components should be added to the entryComponents
of that module.
During runtime, you will load that module to get access to the components declared inside if it. You don't really need a module but that's a unit of packaging in Angular so you can't avoid using it. Now, once you get a module, you have to options depending on whether the module is built using AOT or not.
If it's built using AOT, you just get the exported factory class from the module and create a module instance:
System.import('path/to/module').then((module)=>{
const moduleFactory = module.moduleFactoryClassName;
const moduleRef = moduleFactory.create(this.parentInjector);
const resolver = moduleRef.componentFactoryResolver;
const compFactory = resolver.resolveComponentFactory(AComponent);
}
If it's not built using AOT, you have to compile it using JIT compiler:
System.import('path/to/module').then((module)=>{
const moduleFactory = this.compiler.compileModuleSync(module.moduleClassName);
const moduleRef = moduleFactory.create(this.parentInjector);
const resolver = moduleRef.componentFactoryResolver;
const compFactory = resolver.resolveComponentFactory(AComponent);
}
Then you can add dynamic components wherever you want using techniques described in this article: Here is what you need to know about dynamic components in Angular