Home > OS >  Webpack Module Federation loads chunks from wrong URL
Webpack Module Federation loads chunks from wrong URL

Time:10-15

I am building a project with webpack module federation with the following setup:

  • React host (running on localhost:3000)
  • Angular Remote 1 (running on localhost:4201)
  • Angular Remote 2 (running on localhost:4202)

The goal is to get both remotes working. If I only run one of the and remove the other it is working perfectly.

The issue I am facing is that when the remotes are loaded, __webpack_require__.p is set by one of the remotes' script and therefore the other remote's chunk is loaded from the wrong url.

Here is the error I get:

Remote loaded from wrong URL

My module federation config is the following:

  • React host:
.
.
.
new ModuleFederationPlugin({
      name: "react_host",
      filename: "remoteEntry.js",
      remotes: {
        angular_remote_1: "angular_remote_1@http://localhost:4201/angular_remote_1.js",
        angular_remote_2: "angular_remote_2@http://localhost:4202/angular_remote_2.js"
      },
      exposes: {},
      shared: {
        ...deps,
        react: {
          singleton: true,
          requiredVersion: deps.react,
        },
        "react-dom": {
          singleton: true,
          requiredVersion: deps["react-dom"],
        },
      },
    }),
.
.
.
  • Angular Remote 1
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
    output: {
        publicPath: "auto",
        uniqueName: "angular_remote_1",
        scriptType: "text/javascript"
    },
    optimization: {
        runtimeChunk: false
    },
    experiments: {
        outputModule: true
    },
    plugins: [
        new ModuleFederationPlugin({
            name: "angular_remote_1",
            library: { type: "var", name: "angular_remote_1" },
            filename: "angular_remote_1.js",
            exposes: {
                './angularRemote1': './src/loadAngularRemote1.ts',
            },
            shared: ["@angular/core", "@angular/common", "@angular/router"]
        })
    ],
};
  • Angular Remote 2
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");

module.exports = {
    output: {
        publicPath: "auto",
        uniqueName: "angular_remote_2",
        scriptType: "text/javascript"
    },
    optimization: {
        runtimeChunk: false
    },
    experiments: {
        outputModule: true,
    },
    plugins: [
        new ModuleFederationPlugin({
            name: "angular_remote_2",
            library: { type: "var", name: "angular_remote_2" },
            filename: "angular_remote_2.js",
            exposes: {
                './angularRemote2': './src/loadAngularRemote2.ts',
            },
            shared: ["@angular/core", "@angular/common", "@angular/router"]
        })
    ],
};

Thins I have tried so far:

  • Playing around with public path (between auto and hardcoded)
  • Setting a custom chunkLoadingGlobal for both remotes (not the host)

The exact reproduction of this issue can be found here: https://github.com/BarniPro/react-host-angular-remotes-microfrontend

Any help is greatly appreciated.

CodePudding user response:

The issue can be solved by setting the topLevelAwait experiment to true in the remotes's webpack.config.js:

experiments: {
    topLevelAwait: true,
},

This results in the two remotes loading in sync which prevents the paths from overriding each other.

Another update I had to make was disabling the splitChunks option in the remotes' optimization settings (see SplitChunksPlugin):

optimization: {
    runtimeChunk: false, // This is also needed, but was added in the original question as well
    splitChunks: false,
}

The Github repo has been updated with the working solution.

  • Related