Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to load dynamic external components into Angular application

I'm facing a problem with Angular application.

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.

The market should download files (js/ts/bunlde..??) into a specific folder.

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

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.

I've tried many solutions, using "require" and "System.import" but both fails when the path to load is dynamically generated.

Is this should be possible ? I can change my code structure; change external widgets.. (for example widgetB is not yet transpiled,...)

In fact I'm looking for a "plugin system" with an Angular4/webpack application.

like image 260
jano42 Avatar asked Aug 04 '17 09:08

jano42


People also ask

How do I load dynamic components in Angular 13?

Dynamically load components in Angular 12 and 13 In the html template, there is a with viewContainerRef. We use ViewChild('viewContainerRef') to obtain the ViewContainerRef. Moreover, we declare ComponentRef array to release the memory of FoodCardComponent in ngOnDestroy to avoid memory leaks.

What is dynamic components in Angular?

What dynamic components are. Dynamic means, that the components location in the application is not defined at buildtime. That means, that it is not used in any angular template. Instead, the component is instantiated and placed in the application at runtime.


1 Answers

I'm doing exactly the same. And I explain the details in this talk at NgConf.

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.

Then, each plugin should be packaged as a module and all exported components should be added to the entryComponents of that module.

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.

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 = moduleRef.componentFactoryResolver;
    const compFactory = resolver.resolveComponentFactory(AComponent);
}

If it's not built using AOT, you have to compile it using JIT compiler:

System.import('path/to/module').then((module)=>{
    const moduleFactory = this.compiler.compileModuleSync(module.moduleClassName);
    const moduleRef = moduleFactory.create(this.parentInjector);
    const resolver = moduleRef.componentFactoryResolver;
    const compFactory = resolver.resolveComponentFactory(AComponent);
}

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

like image 70
Max Koretskyi Avatar answered Oct 08 '22 21:10

Max Koretskyi