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:
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.