Angular 5 - load modules (that are not known at compile time) dynamically at run-time
Asked Answered
F

2

6

Is it possible for Angular 5 to load modules/components that are not known at compile time, but during runtime dynamically?

I guess this won't work using webpack but maybe using system.js?

EDIT:

The whole idea is to build a plugin based application where individual plugins are dropped inside a plugin folder, angular will pick it automatically, without having to recompile and deploy the whole angular app. Where plugins are separate pieces of functionalities. Of course there are routes navigation etc. Means that once angular understands there is a new plugin it should add some dynamic navigation so user will be able to navigate to the plugin, etc.

Ferity answered 2/2, 2018 at 20:30 Comment(0)
T
3

Well, while there are complexities involved, you could try it. Depends on your code base I guess. The router exposes config property, holding its current config, and a resetConfig(routes: Routes) method for reseting configuration. You can start from there, and add, say, components on the fly.

The components do have to be reachable, though. Perhaps dynamically created, as mentioned in the other answer. Alternatively, your config could include something like this:

constructor(private router: Router) {}

private addPlugin(routePath, pluginName, pluginPath) {
    const currentConfig = this.router.config;
    currentConfig.push({
        path: routePath,
        loadChildren: `precompiled-modules/${pluginPath}#${pluginName}`,
    });
    this.router.resetConfig(currentConfig);
}

You would have to get the pluginPath and pluginName somehow - maybe calculate it by convention, maybe a lil' backend helper that gets this, maybe have the array of it preconfigured and already loaded or similar. I also assume you would have a really good test system, to make sure your plugins are "compatible". And finally, teach webpack/systemjs how to have the modules ready. All in all, it is not impossible, but it involves some groundwork.

That said, Angular 6 is around the corner, and with it, Angular Elements. Elements will provide a way to compile your modules as web components and "export" them, so that they can get used anywhere (not necessarily in Angular apps). Think jQuery plugins - there is a base jQuery.min.js you need to have loaded, but apart from that you don't think about it any more, you just use your new elements. It's similar with Angular Elements - you export what is basically a Web component. There is a "loader" part (jquery.min.js equivalent), and your Element bundle. But then your component is just another HTML node, with properties, attributes, bindings, events, you don't care any more, just like you don't about inputs.

It might be worth the wait, take a look and decide for yourself.

Tesler answered 19/2, 2018 at 9:49 Comment(3)
You got this working in runtime? I tried some several solution but webpack (cli) creates chunkfiles for every module reference mentioned in the loadChildren property. If I would extend the router when I'm already at runtime I get a module not found exception and the application fails. Angular Elements looks really promising to load up elements on the fly! But in our project it is mainly routing to new and/or updated 'Modules'Sunward
No, did not try this on production build. Regarding Angular Elements, it's out there now, but it's quite big bundles (e.g. 1mb). As for webpack, you have to create configurations and play quite a bit to get the propper bundles taht would be loadable this way, and you have to "teach" the main bundle about these extras. That would probably involve some manual work too. Probably not worth it for most cases, but if you're one of the cases where it is worth it, then it's also worth messing with it all manually.Tesler
Thanks! Will dive more into that, in the meantime I posted a question regarding this too #50149516. Indeed regarding AE, they are still quite big in file size, but its still pretty 'young' :)Sunward
R
2

You could look at Dynamic Component Loading: https://angular.io/guide/dynamic-component-loader

It allows you to add components dynamically at runtime.

Reade answered 2/2, 2018 at 20:38 Comment(4)
Will it work for this scenario where I build my angular app, deploy it, and later build one single component, drop it inside the app folder and the angular app will pick it without having to recompile the whole application and redeploy?Ferity
P.S. Thanks for the great Angular courses on Pluralsight :)Ferity
Have you seen the discussion here: #41438698Reade
I created a repository on github with a solution which might help. It uses Angular 6 libraries and 1 base applications which load up the UMD bundled libraries lazily; github.com/lmeijdam/angular-umd-dynamic-example If you have any suggestions, please feel free to add!Sunward

© 2022 - 2024 — McMap. All rights reserved.