目前我正在开发一个托管在客户端服务器上的项目.对于新的"模块",无意重新编译整个应用程序.也就是说,客户端希望在运行时更新路由器/延迟加载的模块.我已经尝试了几件事,但我无法让它发挥作用.我想知道你们中是否有人知道我还能尝试什么或者我错过了什么.
有一点我注意到,在构建应用程序时,我尝试使用angular cli的大部分资源都被webpack捆绑成单独的块.这似乎是合乎逻辑的,因为它使用了webpack代码拆分.但是如果在编译时模块还不知道怎么办(但是编译后的模块存储在服务器的某个地方)?捆绑不起作用,因为它找不到要导入的模块.并且使用SystemJS将在系统上找到时加载UMD模块,但也通过webpack捆绑在一个单独的块中.
我已经尝试过的一些资源;
我已经尝试并实现了一些代码,但目前还没有工作;
使用普通的module.ts文件扩展路由器
this.router.config.push({
path: "external",
loadChildren: () =>
System.import("./module/external.module").then(
module => module["ExternalModule"],
() => {
throw { loadChunkError: true };
}
)
});
Run Code Online (Sandbox Code Playgroud)
正常SystemJS导入UMD捆绑包
System.import("./external/bundles/external.umd.js").then(modules => {
console.log(modules);
this.compiler.compileModuleAndAllComponentsAsync(modules['External']).then(compiled => {
const m = compiled.ngModuleFactory.create(this.injector);
const factory = compiled.componentFactories[0];
const cmp = factory.create(this.injector, [], null, m);
});
});
Run Code Online (Sandbox Code Playgroud)
导入外部模块,不使用webpack(afaik)
const url = 'https://gist.githubusercontent.com/dianadujing/a7bbbf191349182e1d459286dba0282f/raw/c23281f8c5fabb10ab9d144489316919e4233d11/app.module.ts';
const importer = (url:any) => Observable.fromPromise(System.import(url));
console.log('importer:', …Run Code Online (Sandbox Code Playgroud) Angular 5是否可以加载在编译时未知但在运行时动态的模块/组件?
我想这可能无法使用webpack但可能使用system.js?
编辑:
整个想法是构建一个基于插件的应用程序,其中单个插件被放入插件文件夹中,angular将自动选择它,而无需重新编译和部署整个角度应用程序.插件是独立的功能.当然有路线导航等.意味着一旦角度理解有一个新的插件,它应该添加一些动态导航,以便用户将能够导航到插件等.
这是我正在尝试实现的目标:我想使用“插件”创建一个应用程序,我所说的插件是:
另一个可以部署在远程主机上并显示在我的应用程序中的角度组件/模块。
看来我不能直接使用 webpack 做这样的事情,我应该使用 SystemJs 来动态加载模块。
欢迎使用 SystemJs 和 Webpack (ng cli) 提供任何建议,以及如何调用远程模块并加载它们的示例。
考虑; JHipster生成基础项目.Angular 4是客户端框架.Webpack捆绑了客户端资产.
我们的想法是构建一个可插拔的管理仪表板(可扩展).将具有主要结构和页面的基础系统.其他团队可以构建自己的插件(页面)并在运行时将其附加到现有系统.因此,我们需要从远程存储库URL加载插件模块,这些URL将从服务器端发送(或者如果有任何更好的想法请通知我).
我构建了一个原型来模拟主流.但是,我遇到了很多障碍.主要是在运行时加载插件模块,使用Webpack编译我们的项目.
Webpack将使用模块ID(资源)替换所有模块名称.
换一种说法:
首先要了解的是Webpack无法动态加载构建期间未知的模块.这继承了Webpack构建依赖关系树的方式,并在构建期间收集模块标识符.它完全没问题,因为Webpack是一个模块捆绑器,而不是模块加载器.因此,您需要使用模块加载器,现在唯一可行的选项是SystemJS(资源).
我在互联网上发现的与这个主题相关的所有文章都说它可行,但它会很复杂.从远程URL加载模块我没有太多运气.我一直在找东西说" 是的,这可能做x ",然后我遇到了一些错误,并寻找那个找别人说" 是的,这是不可能的 ".我曾尝试使用SystemJs加载器来延迟加载插件模块作为以下片段,但没有运气!
@Component({
providers: [
{
provide: NgModuleFactoryLoader,
useClass: SystemJsNgModuleLoader
}
]
})
export class ModuleLoaderComponent {
constructor(private _injector: Injector,
private loader: NgModuleFactoryLoader) {
}
ngAfterViewInit() {
this.loader.load('app/t.module#TModule').then((factory) => {
const module = factory.create(this._injector);
const r = module.componentFactoryResolver;
const cmpFactory = r.resolveComponentFactory(AComponent);
// create a component and attach it to the view
const componentRef = cmpFactory.create(this._injector);
this.container.insert(componentRef.hostView);
})
}
}Run Code Online (Sandbox Code Playgroud)
所以我想知道是否真的可以使用Angular 4和Webpack来做这样的系统?有没有关于这个主题的任何好的文档或一个工作的例子?我应该考虑这种系统的另一个客户端框架吗?
UPDATE
感谢 这篇非常有见地的文章,我能够使用从端点获取的动态模板动态创建组件,但是这些组件是使用 RuntimeCompiler 在运行时编译的,在使用 AoT 编译(又称生产时)时会禁用该编译器。
有人知道适用于 AoT 的类似解决方案吗?
我的要求是:
angular ×5
angular5 ×3
systemjs ×3
webpack ×3
angular-cli ×1
javascript ×1
pluggable ×1
plugins ×1