2
votes

Basically i want to create a dynamic plugin system. I need to be able to deploy new plugins without having to redeploy the main plugin system.

Basically if I was to use SystemJS i could just do something like

System.import(url).then(plugin => {
  this.createComponent(plugin.default);
});

url being the dynamic thing - could read this from a db or config, etc.

The above could would work - except i use the Angular CLI, which uses Webpack. Using the CLI is a choice made to simply the whole project - so I'm stuck with Webpack and the CLI.

Since the Angular CLI does a lot of abstraction, I can't modify the webpack config (well I can, but then i have to maintain it manually, which again would break the simplicity).

Webpack is not a module loading, but a bundler - meaning it is supposed to know these modules beforehand, and i can't just drop a new module somewhere and update the config for it to load it dynamically.

What would my options be here?

EDIT: Webpack has its own System.import, but it has some checking to see if the url is static or dynamic. I could live with passing a static folder and having to drop plugins into that folder - that just doesn't seem to work from anywhere but inside the application itself.

1
Had the same requirement when we started a year ago. There was no choice but to use systemjs and not use the angular-cli. I don't see anything since then that would allow the cli to work more "dynamically" but would like to know if there is.Steverob2k
Webpack is not a module loading, but a bundler - that's exactly right, so there should be no choice between Webpack and SystemJS, use both. They are different tools for different tasks. I'm working on a plugin based system and use both nowMax Koretskyi
@Maximus yeah, but a little worried SystemJS would be overkill - also i would need to hack it somehow to override webpacks System.import. It irks me some...Per Hornshøj-Schierbeck
@Maximus how do you deal with entryComponents when loading components dynamically ?Milad
@SystemJS follows the proposal for dynamic modules loading so it should be availble in browsers over time anyway. Also the article Here is what you need to know about dynamic components in Angular might help you with your journeyMax Koretskyi

1 Answers

1
votes

Unfortunately, as far as I know, at the end of the day you need to add your dynamic component to the entryComponents of the current module, otherwise Angular won't let you load it dynamically and it will complain.

So either way, you've got to load the component statically and put it inside the entryComponents, so not much point in using SystemJS or Something else, you could just create a dictionary and use it when ever you want :

import {MyComponentClass} from 'somewhere';

const dictionary = {
    component1  = MyComponentClass
}

 this.createComponent(dictionary[urlOrName]);

The other possible solution would be to create a module for each component that you're going to load dynamically and then add that component to the entryComponents of that module, that way, you could be able to import/download that module dynamically but I'm not sure if you could add that dynamic module to the root module dynamically or not ( the way router is doing it when lazyLoading !~~).

Angular used to be much simpler regarding the dynamic components before they introduced AOT, they honestly killed the simplicity with introducing AOT