Search code examples
angularwebpackangular-materialwebpack-module-federation

Angular mat-select and webpack module federation event problem


I have two Angular Apps, a shell app and a content app inside a MonoRepo. The shell app is like a landing page which displays a card and with click on it, the content app is displayed.

Within this content app I am using a mat-select control, which does not close the panel on outside click -> Problem! It seems that the outside click event is catched by the shell app. If I use a mat-select within the shell app, everything works fine.

This is my shell webpack config:

const webpack = require("webpack");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
  output: {
    publicPath: "http://localhost:4200/",
    uniqueName: "home",
  },
  optimization: {
    runtimeChunk: false,
  },
  plugins: [
    new ModuleFederationPlugin({
      shared: {
        "@angular/core": { eager: true, singleton: true },
        "@angular/common": { eager: true, singleton: true },
        "@angular/router": { eager: true, singleton: true }
      },
    }),
  ],
};

content webpack config:

const webpack = require("webpack");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
  output: {
    publicPath: "http://localhost:4201/",
    uniqueName: "contentModul"
  },
  optimization: {
    runtimeChunk: false,
  },
  plugins: [
    new ModuleFederationPlugin({
      name: "content",
      library: { type: "var", name: "content" },
      filename: "remoteEntry.js",
      exposes: {
        ContentModule:
          "./projects/content/src/app/content/content.module.ts",
      },
      shared: {
        "@angular/core": { eager: true, singleton: true },
        "@angular/common": { eager: true, singleton: true },
        "@angular/router": { eager: true, singleton: true }
      },
    }),
  ],
};

and here my routing:

    import { NgModule } from "@angular/core";
    import { Routes, RouterModule } from "@angular/router";
    import { HomeComponent } from "./home/home.component";
    import { PageNotFoundComponent } from "./static-pages/page-not-found/page-not-found.component";
    import { loadRemoteModule } from "./utils/federation-utils";
    
    const routes: Routes = [
      { path: "", redirectTo: "home", pathMatch: "full" },
      { path: "home", component: HomeComponent },
      {
        path: "content",
        loadChildren: () =>
          loadRemoteModule({
            remoteName: "content",
            remoteEntry: "http://localhost:4201/remoteEntry.js",
            exposedModule: "ContentModule",
          }).then((m) => m.ContentModule)
      },
      { path: "**", component: PageNotFoundComponent }
    ];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}

Do you have a clue what´s missing/wrong?

Thx!


Solution

  • I had the exact same issue. The problem that I encountered had to do with the imports of an Angular module. I imported Angular's BrowserModule in my micro frontends which was wrong. This module should only be imported in your shell application's root module.

    The micro frontends should only import CommonModule instead. If you import BrowserModule instead, this will break the Angular runtime and result in errors like events not being properly catched.