1

ModuleFederationPlugin Webpack 5 Parent webpack configuration :

publicPath: "http://localhost:3000/parentapp/",

new  ModuleFederationPlugin({
            name: "parent",
            shared: {
              react: {
                requiredVersion: deps.react,
                import: "react", 
                shareKey: "react", 
                shareScope: "default", 
                singleton: true, 
              },
              "react-dom": {
                requiredVersion: deps["react-dom"],
                singleton: true,
              }
            },
          }),

app 1 webpack configuration:

publicPath: "http://localhost:3001/app1",

new ModuleFederationPlugin({
            name: "app1",
            library: { type: "var", name: "app1" },
            filename: 'remoteEntry.js',
            exposes: {
              "./App": "./src/App",
            },
            shared: ["react", "react-dom", "react-apollo"],
          }),

app 2 webpack configuration :

publicPath: "http://localhost:3002/app2",

new ModuleFederationPlugin({
            name: "app2",
            library: { type: "var", name: "app2" },
            filename: 'remoteEntry.js',
            exposes: {
              "./App": "./src/App",
            },
            shared: ["react", "react-dom", "react-apollo"],
          }),

Parent Index.html consists of script element in <head> tag:

<script src="http://localhost:3001/app1/remoteEntry.js"></script>
<script src="http://localhost:3002/app2/remoteEntry.js"></script>

Parent App.js file :

Using lazy loading and suspense to get app1 container and app2 container:

function loadComponent(scope, module) {
        return async () => {
            // Initializes the share scope. This fills it with known provided modules from this build and all remotes
            await __webpack_init_sharing__("default");

            const container = window[scope]; // or get the container somewhere else
            // Initialize the container, it may provide shared modules
            await container.init(__webpack_share_scopes__.default);
            const factory = await window[scope].get(module);
            const Module = factory();
            return Module;
        };
    }

const ComponentApp1 = React.lazy(
        loadComponent('app1', './App')
     );

     const ComponentApp2 = React.lazy(
         loadComponent('app2', './App')
     );

//There are two Navlinks to route to app1 and app2 respectively.
                    
 <NavLink to="/app1">App 1</NavLink>
  <NavLink to="/app2">App 2</NavLink>


<Router basename="/" history={history}>
                    <Switch>
                        <Route path="/app1">
                           <Suspense fallback={<img src={loading} alt="loading" />}>
                               <ComponentApp1 />
                           </Suspense>
                        </Route>
                        <Route path="/app2">
                           <Suspense fallback={<img src={loading} alt="loading" />}>
                               <ComponentApp2 />
                           </Suspense>
                        </Route>
                     </Switch>
</Router>

If any first app is clicked either app1 or app2 then its app container is remotely loading and its content is being shared with parent app but while click another app which was not clicked previously is clicked then its app container doesn't load and the remote entry doesn't take place for the second clicked app. Also if page refresh is done for not loaded child app then it gets loaded but then the other one doesn't connect when clicked.

Please provide any solution or anything which is being missed for module federation remote entry for multiple apps with parent app.

1 Answers1

2

i solved with add unique name on my webpack

output: {
  publicPath: 'http://localhost:3000/',
  uniqueName: 'users',
},
experiments: {
  topLevelAwait: true,
},
optimization: {
  runtimeChunk: false,
},
plugins: [
  ...config.plugins,
  new ModuleFederationPlugin({
    name: 'users',
    filename: 'usersEntry.js',
    exposes: {
      './UsersEntry': './src/app/components/UsersEntry',
    },
........
FAOZI
  • 67
  • 6