Repository navigation
Federate module hot reload not working #3038
Description
- Operating System: Windows
- Node Version: v12.16.1
- NPM Version: 6.13.4
- webpack Version: 5.18.0
- webpack-dev-server Version : 3.11.2
- Browser: All
- This is a bug
- This is a modification request
App Container config
const ReactRefreshPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require("webpack").container
.ModuleFederationPlugin;
const path = require("path");
const deps = require("./package.json").dependencies;
module.exports = {
entry: "./src/index",
target:"web",
mode: "development",
devServer: {
contentBase: path.join(__dirname, "public"),
port: 3001,
hotOnly:true,
open:true
},
output: {
publicPath: "auto",
},
resolve: {
extensions: [".js", ".jsx", ".json", ".ts", ".tsx"],
},
module: {
rules: [
{
test: /bootstrap\.tsx$/,
loader: "bundle-loader",
options: {
lazy: true,
},
},
{
test: /\.tsx?$/,
loader: "babel-loader",
exclude: /node_modules/,
options: {
plugins: ['react-refresh/babel'],
presets: ["@babel/preset-react", "@babel/preset-typescript"],
},
},
{
enforce: "pre",
test: /\.js$/,
loader: "source-map-loader",
},
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2,
sourceMap: true,
},
},
{
loader: 'postcss-loader',
options: {
options: {}
}
},
],
},
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
'resolve-url-loader',
'sass-loader',
],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader',
],
},
],
},
plugins: [
new ModuleFederationPlugin({
name: "appshell",
filename: "remoteEntry.js",
remotes: {
mfsectors: "mfsectors@http://localhost:3002/remoteEntry.js",
},
exposes: {
"./routes": "./src/routes",
"./src/store/**": "./src/store"
},
shared: {
...deps,
react: {
eager: true,
singleton: true,
requiredVersion: deps.react,
},
"react-dom": {
eager: true,
singleton: true,
requiredVersion: deps["react-dom"],
},
},
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "public", "index.html"),
}),
new ReactRefreshPlugin({
exclude: [/node_modules/, /bootstrap\.tsx$/],
}),
],
};Federate appconfig
const ReactRefreshPlugin = require("@pmmmwh/react-refresh-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const ModuleFederationPlugin = require("webpack").container
.ModuleFederationPlugin;
const path = require("path");
const deps = require("./package.json").dependencies;
module.exports = {
entry: "./src/index.ts",
mode: "development",
devServer: {
contentBase: path.join(__dirname, "public"),
port: 3002,
hotOnly:true
},
output: {
publicPath: "auto",
},
resolve: {
extensions: [".js", ".jsx", ".json", ".ts", ".tsx"],
},
module: {
rules: [
{
test: /bootstrap\.tsx$/,
loader: "bundle-loader",
options: {
lazy: true,
},
},
{
test: /\.tsx?$/,
loader: "babel-loader",
exclude: /node_modules/,
options: {
plugins: ['react-refresh/babel'],
presets: ["@babel/preset-react", "@babel/preset-typescript"],
},
},
{
enforce: "pre",
test: /\.js$/,
loader: "source-map-loader",
},
{
test: /\.css$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2,
sourceMap: true,
},
},
{
loader: 'postcss-loader',
options: {
options: {}
}
},
],
},
{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
'resolve-url-loader',
'sass-loader',
],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader',
],
},
],
},
plugins: [
new ModuleFederationPlugin({
name: "mfsectors",
filename: "remoteEntry.js",
remotes: {
appshell: "appshell@http://localhost:3001/remoteEntry.js",
},
exposes: {
"./routes": "./src/routes",
"./Pages/SectorsList" : "./src/Pages/SectorsList.tsx"
},
shared: {
...deps,
react: {
eager: true,
singleton: true,
requiredVersion: deps.react,
},
"react-dom": {
eager: true,
singleton: true,
requiredVersion: deps["react-dom"],
},
},
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, "public", "index.html"),
}),
new ReactRefreshPlugin({
exclude: [/node_modules/, /bootstrap\.tsx$/],
}),
],
};Expected Behavior
App Container auto reload when federate app change
Actual Behavior
Hello,
I have finally succeeded in setting up my software environment (Dashboard...) in micro-frontend thanks to Module Federation. Only I notice that the live & hot reloading doesn't work when I modify a federate module:
I explain myself, I work on an App Shell which contains all my micro frontends (an app which manages the connection, the authorization in RBAC, the redux provider, etc...) and which will control all the other federated applications, only the automatic refresh will not reload the port 3001(AppShell) if I work on an app of the port 3002.
While searching on the internet I could find some unanswered questions about this, I would like to understand how is it possible to reload the app container automatically?
For Bugs; How can we reproduce the behavior?
For Features; What is the motivation and/or use-case for the feature?
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Activity
bedrich-schindler commentedon Feb 22, 2021
I met the same issue last week. Hot reload module is not working when using
webpack-dev-serverv3 withwebpackv5. You need to upgradewebpack-dev-serverto latest beta version which includes bug fix (unfortunately, it will not be fixed in v3)See: #2758 and #2961
Hope this helps.
alexander-akait commentedon Mar 23, 2021
Yep, only v4 (beta right now supports module federation), we are working on the next beta release with more fixes, stable release will be in the end of month
wdfinch commentedon Apr 12, 2021
Hi, I'm trying to use HMR in a module federation POC app. I've been following a bunch of related issues on this and I'm not sure where this stands. While I can get my app to start via web-pack-dev server, I get an error whenever I edit a file:
Cannot set property './src/App.tsx' of undefinedI'm currently using:
webpack-dev-server 4.0.0-beta.2webpack: 5.31.0My module federation config is as follows:
Is HMR replacement possible with module federation right now or is this still under development?
clyfish commentedon Aug 19, 2022
@wdfinch I have a workaround for your problem by excluding the module federation entry in
html-webpack-plugin, because it's included in the output HTML by mistake.You can use the
chunksorexcludeChunksoptions ofhtml-webpack-plugin.ItayElgazar commentedon Jan 10, 2023
@clyfish
Based on your example, could you tell me exactly what these chunks are? Can you paste here a real-world example?
Thanks!
clyfish commentedon Jan 16, 2023
@ItayElgazar You can check the HTML outputted by webpack yourself. Right-click and choose View Page Source.
ModuleFederationPlugincreates anentryto be used by other apps, buthtml-webpack-pluginincludes that entry into HTML by mistake.ESoch commentedon Mar 9, 2023
For clarity's sake, as someone who went through this thread and was also confused with understanding what chunk names should be and was looking for a real-world example of the HtmlWebpack
excludeChunksfix, here it is.Let's say you have a simple Webpack configuration that looks like this:
The above is an example where we're excluding the
remoteEntry.js(i.e module federation entry) from the host's ownindex.html.An alternative implementation where the
chunk:configuration is used is as follows: