angularwebpack

Shared module is not available for eager consumption - Angular 13


I've read other answers and haven't had any success implementing federated modules with Angular 13. I always get the 'Shared module is not available for eager consumption' message.

TL;DR:

  1. Double-check your public path in your custom webpack config - it may be missing a trailing / which WebPack may erroneously be reporting as "unavailable for eager consumption".
  2. Check the routing - your MFE/remote module will receive the child routes after the host module's routing (so if your host is routing to the MFE when hitting the route 'login', your MFE will not get the 'login' path, it will get an empty path (see update 2 below).
  3. Bootstrapping (update 1 below) may (or may not) be required.

Host App webpack.config.ts:

export const webpackConfig: Configuration = {
  output: {
    publicPath: 'http://localhost:4200',
    uniqueName: 'host',
  },
  plugins: {
    new container.ModuleFederationPlugin({
      name: "host",
      remotes: {
        "remote-login": "login@http://localhost:4201/remoteEntry.js"
      }
      shared: [
        "@angular/core",
        "@angular/common",
        "@angular/router",
        "@angular/common/http",
      ]
    })
  ]
}

export default webpackConfig;

The remote app:

export const webpackConfig: Configuration = {
  output: {
    publicPath: 'http://localhost:4201',
  },
  optimization: { runtimeChunk: false },
  experiments: { outputModule: true },
  plugins: {
    new container.ModuleFederationPlugin({
      name: "login",
      filename: "remoteEntry.js",
      exposes: {
        LoginComponent: './projects/module1/src/app/pages/login/login.component.ts',
      },
      shared: [
        "@angular/core",
        "@angular/common",
        "@angular/router",
        "@angular/common/http",
      ]
    })
  ]
}

export default webpackConfig;

Update 1:

I've tried using a 'bootstrap' file. Using this in the main.ts file: import('bootstrap').catch(err => console.error(err)) and now see the following error in the console - which appears solely related to the new bootstrap process: ChunkLoadError: Loading chunk projects_host_src_bootstrap_ts failed.

_Note: This error was because the public path defined in the webpack.config.ts was missing a trailing slash. Leading it to try to load the chunk from http://localhost:4200projets_host_src_bootstrap_ts (missing the / after the port number).

Update 2:

I'm now getting Error: ASSERTION ERROR: NgModule 'LoginComponent' is not a subtype of NgModuleType. So at least I'm back in 'Angular-error-land'.

I had to set the routes in the LoginModule (home of the LoginComponent) to be:

export const routes: Routes = [
  {
    path: '', //Note: empty path, _not_ matching the app's 'login' path
    loadChildren: () => import('./login/login.component').then(m => m.LoginComponent),
  }
]

Update 3: It's working

So I changed the MFE (the LoginModule) routing to be non-lazy and it worked!

export const routes: Routes = [
  {
    path: '', //Note: empty path, _not_ matching the app's 'login' path
    component: LoginComponent,
  }
]

I'm going to roll back the bootstrap changes and see if they are required, but it's at least using the federated module now!


Solution

    1. Double-check your public path in your custom webpack config - it may be missing a trailing / which WebPack may erroneously be reporting as "unavailable for eager consumption".

    2. Check the routing - your MFE/remote module will receive the child routes after the host module's routing (so if your host is routing to the MFE when hitting the route 'login', your MFE will not get the 'login' path, it will get an empty path.

    3. Bootstrapping may (or may not) be required.