module federation returns blank in dev when connecting to remote repo, works in prod
See original GitHub issueI have 2 repos, both microfrontends, created with Module Federation and custom webpack config.
The shared repo is deployed. In the other repo I want to connect to the remote shared version, but if I do that in the webpack.dev.config.ts, where the mode is set to “development”, it shows me a blank page with no error.
When I change the mode to “production” it works - I have copied the prod config to the dev, commented out the differences, turned them on one by one and narrowed it down to the mode being the problem.
Based on some tutorials I saw, it looks like this wasn’t an issue before. I’m using
"webpack": "5.72.1",
"webpack-cli": "4.9.2",
"webpack-dev-server": "4.8.0"
here’s the webpack.dev.config.ts setup that works fine with the mode: “production” and the remote repo given in module federation setup.
const port = 3502;
interface Configuration extends WebpackConfiguration {
devServer?: WebpackDevServerConfiguration;
}
const config: Configuration = {
mode: "production", // TODO works with remote repo in module federation setup
// mode: "development", // TODO doesn't work
output: {},
optimization: {
runtimeChunk: false,
},
devServer: {
port,
host: "0.0.0.0",
hot: true,
historyApiFallback: true,
headers: {
"Access-Control-Allow-Origin": "*",
},
},
module: {
rules: [
{
test: /\.module\.(css|scss)$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[name]_[local]__[hash:base64:5]",
},
sourceMap: true,
},
},
{
loader: "sass-loader",
options: {
sourceMap: true,
},
},
],
},
{
test: /\.(css|scss)$/,
exclude: /\.module\.(css|scss)$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
sourceMap: true,
},
},
{
loader: "sass-loader",
options: {
sourceMap: true,
},
},
],
},
{
test: /\.(ts|js)x?$/i,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"],
},
},
},
{
test: /\.(jpg|jpeg|png|gif|svg)$/,
use: ["file-loader"],
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
alias: {
"@": path.resolve(__dirname, "src"),
"@App": path.resolve(__dirname, "src/App"),
"@Components": path.resolve(__dirname, "src/App/components"),
"@Remote": path.resolve(__dirname, "src/App/components/@remote"),
},
},
plugins: [
new container.ModuleFederationPlugin({
name: "sof",
filename: "remoteEntry.js",
exposes: {
"./Sof": "./src/App/App.tsx",
},
remotes: {
shared: "shared@https://shared-dev.foo/remoteEntry.js", //this doesn't work with mode: "development"
// shared: "shared@http://localhost:6002/remoteEntry.js", //this works in both cases
},
shared: [
{
react: {
singleton: true,
},
},
],
}),
new HtmlWebpackPlugin({
template: "public/index.html",
}),
new MiniCssExtractPlugin({
filename: "[name].[hash].css",
chunkFilename: "[id].[hash].css",
}),
new ForkTsCheckerWebpackPlugin({
async: false,
}),
new ESLintPlugin({
extensions: ["js", "jsx", "ts", "tsx"],
}),
new Dotenv(),
],
// devtool: "inline-source-map", // TODO
};
export default config;
here’s the prod version. e.g. the output is different, but when I changed the output to an empty object in dev config, it works fine.
const config: Configuration = {
mode: "production",
output: {
path: path.resolve("build"),
filename: "[name].bundle.js?v=[contenthash]",
},
module: {
rules: [
{
test: /\.module\.(css|scss)$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: {
localIdentName: "[name]_[local]__[hash:base64:5]",
},
sourceMap: true,
},
},
{
loader: "sass-loader",
options: {
sourceMap: true,
},
},
],
},
{
test: /\.(css|scss)$/,
exclude: /\.module\.(css|scss)$/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
sourceMap: true,
},
},
{
loader: "sass-loader",
options: {
sourceMap: true,
},
},
],
},
{
test: /\.(ts|js)x?$/i,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript"],
},
},
},
{
test: /\.(jpg|jpeg|png|gif|svg)$/,
use: ["file-loader"],
},
],
},
resolve: {
extensions: [".tsx", ".ts", ".js"],
alias: {
"@": path.resolve(__dirname, "src"),
"@App": path.resolve(__dirname, "src/App"),
"@Components": path.resolve(__dirname, "src/App/components"),
"@Remote": path.resolve(__dirname, "src/App/components/@remote"),
},
},
plugins: [
new container.ModuleFederationPlugin({
name: "sof",
filename: "remoteEntry.js",
exposes: {
"./Sof": "./src/App/App.tsx",
},
remotes: {
shared: "shared@https://shared-dev.foo/remoteEntry.js",
},
shared: [
{
react: {
singleton: true,
},
},
],
}),
new HtmlWebpackPlugin({
template: "public/index.html",
}),
new MiniCssExtractPlugin({
filename: "[name].[hash].css",
chunkFilename: "[id].[hash].css",
}),
new ForkTsCheckerWebpackPlugin({
async: false,
}),
new ESLintPlugin({
extensions: ["js", "jsx", "ts", "tsx"],
}),
new Dotenv(),
new CleanWebpackPlugin(),
],
};
export default config;
I want to be able to connect to the remote shared repo without having to make manual changes in webpack. Any idea how to?
Issue Analytics
- State:
- Created a year ago
- Reactions:1
- Comments:10 (5 by maintainers)
hi, so we found a problem with my team. we’ve upgraded all packages to the newest and realised we were missing
eager: true
in webpack module federation config.first we had no error, but after tweaking some packages we’ve ended up with the following error, that eager:true resolved
here’s what fixed the problem for us
please create reproducible repo… it is hard to guess a problem…