Consider; JHipster to generate the base project. Angular 4 is the client-side framework. Webpack bundles the client-side assets.
The idea is building a pluggable admin dashboard (extendable). Will have a base system with main structure and pages. Other teams can build there own plugin (page) and attach it to the existing system at runtime. So we need to load plugins modules from remote repository URLs which will be sent from the server-side (or if there is any better idea please inform me).
I built a prototype to simulate the main flow. However, I faced many obstacles. Mainly with loading the plugins modules at the runtime with using Webpack to compile our project.
Webpack will replace all module names with module IDs (resource).
In other words:
The first thing to understand is that Webpack cannot dynamically load modules that are unknown during build time. This is inherited 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 (resource).
All the article I found on the internet related to this topic keep saying it doable but it will be complicated. I didn't have much luck with loading modules from remote URL. I keep finding stuff which says "yeah this is possible do x", then I hit some error and search for that to find someone else saying "yeah that's not possible". I have tried to use SystemJs loader to lazy load the plugins moduels as the following snippet with no luck yet!
@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);
})
}
}
So I am wondering if it is really possible to do such system using Angular 4 and Webpack? Is there any good documentation about this topic anywhere or a working example? Should I consider another client-side framework for such system?
UPDATE
I found the following answer for a closed issue on Angular-cli repository:
I don't see there being a way to have lazy route detection and AOT together with dynamic runtime lazy routes. You'll need a different build system than the one the CLI provides for that.
SystemJS would allow something like that, but probably not with AOT.
So, how should we achieve this using SystemJS? Still facing lack of documentation about this topic especially with considering Angular 4 (Typescript) as our framework.