我在使用 Angular 应用程序时遇到问题.
I'm facing a problem with Angular application.
我想要一个用 Typscript 编写的带有 (aot) 的 Angular 应用程序.
I would like to have an angular application written in Typscript build with (aot).
目的是显示带有一些小部件的用户仪表板.小部件是一个角度组件.
The aim is to display a user dashboard with some widgets. A widget is an angular component.
我的应用带有一些嵌入式小部件.但是小部件应该通过类似市场的东西来扩展;或手动创建.
My app comes with some embedded widgets. But widgets should be extended by something like a market place; or created manually.
市场应该将文件(js/ts/bunlde..??)下载到特定的文件夹中.
The market should download files (js/ts/bunlde..??) into a specific folder.
然后我的应用程序应该能够加载新的小部件(= ng 组件)并实例化它们.
Then my app should be able to load the new widgets (= ng component) and instanciate them.
我的文件夹结构(制作)
My folder structure (production)
|- 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.所以目的是动态加载文件并实例化包含的组件.
Then when loading the user page, the database say that there is a widgetA. So the aim is to dynamically load files and instanciate included component.
我尝试了很多解决方案,使用require"和System.import",但在动态生成加载路径时都失败了.
I've tried many solutions, using "require" and "System.import" but both fails when the path to load is dynamically generated.
这应该可能吗?我可以改变我的代码结构;更改外部小部件..(例如,widgetB 尚未转译,...)
Is this should be possible ? I can change my code structure; change external widgets.. (for example widgetB is not yet transpiled,...)
事实上,我正在寻找一个带有 Angular4/webpack 应用程序的插件系统".
In fact I'm looking for a "plugin system" with an Angular4/webpack application.
推荐答案我正在做的完全一样.我在 NgConf 的本次演讲中解释了细节.
I'm doing exactly the same. And I explain the details in this talk at NgConf.
首先要了解的是,Webpack 无法动态加载构建时未知的模块.这是 Webpack 在构建时构建依赖树和收集模块标识符的方式所固有的.这很好,因为 Webpack 是一个模块打包器,而不是模块加载器.所以你需要使用模块加载器,现在唯一可行的选择是 SystemJS.
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.
然后,每个插件都应该打包成一个模块,所有导出的组件都应该添加到该模块的entryComponents中.
Then, each plugin should be packaged as a module and all exported components should be added to the entryComponents of that module.
在运行时,您将加载该模块以访问内部声明的组件.您实际上并不需要模块,但它是 Angular 中的一个包装单元,因此您无法避免使用它.现在,一旦您获得一个模块,您必须根据模块是否使用 AOT 构建来进行选择.
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.
如果它是使用 AOT 构建的,您只需从模块中获取导出的工厂类并创建一个模块实例:
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 = moduleRefponentFactoryResolver; const compFactory = resolver.resolveComponentFactory(AComponent); }如果它不是使用 AOT 构建的,则必须使用 JIT 编译器进行编译:
If it's not built using AOT, you have to compile it using JIT compiler:
System.import('path/to/module').then((module)=>{ const moduleFactory = thispilerpileModuleSync(module.moduleClassName); const moduleRef = moduleFactory.create(this.parentInjector); const resolver = moduleRefponentFactoryResolver; const compFactory = resolver.resolveComponentFactory(AComponent); }然后您可以使用本文中描述的技术在任何地方添加动态组件:这里是你需要了解的关于 Angular 中的动态组件
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
更多推荐
如何将动态外部组件加载到 Angular 应用程序中
发布评论