Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 690
Patrick Dench Avatar asked Jan 26 '26 15:01

Patrick Dench


2 Answers

To the original error message, there's a Webpack doc on this specific error.

In short, you need an async boundary (which is created by the existence of files bootstrap.js + index.js) that ensure shared dependencies are awaited when loaded on the client side:

index.js:

import('./bootstrap.js');

bootstrap.js:

import React from 'react';

// ... the rest of application root component

You could also add eager: true to the shared dependencies, but this will add them to the initial chunk regardless if they are used.

like image 95
Bruno Peres Avatar answered Jan 28 '26 20:01

Bruno Peres


I migrated my nx angular 14 app to webpack federation, and just moved the original main.ts content to the new file bootstrap.ts and update main.ts to:

import('./bootstrap').catch((error) => console.error(error));

and it's working!

like image 30
nitsanzo Avatar answered Jan 28 '26 18:01

nitsanzo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!