'Components with same import in micro-frondends

I am building a React application based on micro-frondends using ModuleFederationPlugin ModuleFederationPlugin from webpack 5.

I have two separated projects (App1 and App2) which expose components and these are used in other project (AppShell).

App1 structure:

components/Button.tsx
App1.tsx

App2 structure:

components/Button.tsx
App2.tsx

Both projects contain component Button.tsx which means that in both project this component has same export. This component is used in App1.tsx (App2.tsx).

Now if I want to use App1 and App2 in AppShell, I always see the Button from App1:

enter image description here

App1 webpack config (App2 is similar):

const HtmlWebpackPlugin = require("html-webpack-plugin");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");


module.exports = {
    entry: "./src/index.tsx",
    output: {
        filename: "test-app1.[contenthash].js",
    },

    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.json'],
    },
    module: {
        rules: [
            {
                test: /\.(ts|js)x?$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
            },
        ],
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({template: './public/index.html'}),
        new ModuleFederationPlugin({
            name: "remoteApp",
            library: { type: "var", name: "remoteApp" },
            filename: "remoteEntry.js",
            exposes: {
                "./MyApp": "./src/MyApp",
            },
            shared: ["react", "react-dom", "@material-ui/core"],
        })
    ]};

AppShell webpack config:

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const {CleanWebpackPlugin} = require("clean-webpack-plugin");
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");


module.exports = {
    entry: "./src/index.tsx",
    output: {
        filename: "app_shell.[contenthash].js",
        path: path.resolve(__dirname, "dist"),
        publicPath: ""
    },

    resolve: {
        extensions: ['.ts', '.tsx', '.js', '.json'],
    },
    module: {
        rules: [
            {
                test: /\.(ts|js)x?$/,
                exclude: /node_modules/,
                loader: 'babel-loader',
            },
            {
                test: /bootstrap\.js$/,
                loader: "bundle-loader",
                options: {
                    lazy: true,
                },
            },
        ],
    },
    plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({template: './public/index.html'}),
        new ModuleFederationPlugin({
            name: "app_shell",
            remotes: {
                "remoteApp-mfe": "remoteApp@http://localhost:8001/remoteEntry.js",
                "remoteApp2-mfe": "remoteApp2@http://localhost:8002/remoteEntry.js",
            },
            shared: {react: {singleton: true}, "react-dom": {singleton: true}, "@material-ui/core": {singleton: true}},
        }),

    ]};

Components usage in AppShell:

import React from "react";

export const AppShell: React.FC = () => {
  // @ts-ignore
  const App1 = React.lazy(() => import("remoteApp-mfe/MyApp"));
  // @ts-ignore
  const App2 = React.lazy(() => import("remoteApp2-mfe/MyApp2"));

  return (
    <>
      <h1>App Shell</h1>
      <React.Suspense fallback="Loading...">
        <App1 />
      </React.Suspense>
      <React.Suspense fallback="Loading...">
        <App2 />
      </React.Suspense>
    </>
  );
};

You can download the test application here.

Do you have any idea how to fix this problem, please? (I know that I can refactor the apps but it is not the solution I am looking for ;)). Thank you.



Solution 1:[1]

change the ModuleFederationPlugin import as

const { ModuleFederationPlugin } = require('webpack').container;

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 helloworldcoder