Search code examples
angularmicro-frontendwebpack-module-federationangular-module-federation

Different approach to utilize Angular Micro-Frontend remotes in the host Angular app


Context:

I have 2 Angular 13 applications, 1 as remote and the other as host and using Module Federation to configure both remote(creating mfe) and host.

All Module Federation examples directs us to load the remote module in the host like this

 {
    path: 'kpi',
    loadChildren: () =>
      loadRemoteModule({
        remoteEntry:
          'http://localhost:58777/dist/megaHrx/remoteEntry.js',
        remoteName: 'mfe1',
        exposedModule: './KpiModule'
      }).then((m) => m.ChangeKpiModule)
  }

While my remote Module is as following:

@NgModule({
  declarations: [ChangeKpiComponent],
  imports: [CommonModule, ChangeKpiRoutingModule],
  providers: [AbbbbbService , StorageService]
})
export class ChangeKpiModule {}

Question:

This works and my Remote component ChangeKpiComponent gets rendered under the route kpi as expected, but what my intention is to use this ChangeKpiComponent via its selector admin-reporting-change-kpi and not by directly loading it via loadChildren in the Routing module.

Is there a way to do that ? If yes, How ?


Solution

  • I think you can achieve that as follows:

    • Expose the component itself also from the remote app (not only the module).
    • Load it in your host app using the loadRemoteModule method.
    • Create a dynamic component based on the returned type from loadRemoteModule.
    • You can create a directive to reuse it anywhere in the host app:
    @Directive({ selector: '[adHost]' })
    export class AdHostDirective {
      constructor(private viewContainerRef: ViewContainerRef) {}
    
      ngOnInit(): void {
        loadRemoteModule({
          remoteEntry: 'http://localhost:58777/dist/megaHrx/remoteEntry.js',
          remoteName: 'mfe1',
          exposedModule: './KpiComponent', // <<<< Use the component expose
        }).then((m) => {
          const componentType = m.ChangeKpiComponent; // <<<< The component's type here.
    
          // Create the component in this view-container:
          this.viewContainerRef.createComponent(componentType);
        });
      }
    }