'Webpack module federation lazy loading remoteEntry.js

Am I able to lazy load apps' entry files when I am using React with ReactRouter? When I enter page there are many requests for remoteEntry.js files for each app I have. I do not want to fetch it at the beginning because of performance. I want to load them when I visit the route to particular app.

enter image description here



Solution 1:[1]

You need to use promise-based dynamic remotes.

For example, rather than define your remote as a URL:

module.exports = {
  plugins: [
    new ModuleFederationPlugin({
      name: 'host',
      remotes: {
        app1: 'app1@http://localhost:3001/remoteEntry.js',
      },
    }),
  ],
};

You could delete this reference in webpack.config.js and define the remote as a promise which will be resolved at runtime:

const loadScope = (url: string, scope: string) => {
  const element: any = document.createElement('script');
  const promise = new Promise((resolve, reject) => {
    element.src = url;
    element.type = 'text/javascript';
    element.async = true;
    element.onload = () => resolve(window[scope]);
    element.onerror = reject;
  });
  document.head.appendChild(element);
  promise.finally(() => document.head.removeChild(element));
  return promise;
};

const loadModule = async (url: string, scope: string, module: string) => {
  try {
    const container = await loadScope(url, scope);
    await __webpack_init_sharing__('default');
    await container.init(__webpack_share_scopes__.default);
    const factory = await container.get(module);
    return factory();
  } catch (error) {
    console.error('Error loading module:', error);
    throw error;
  }
};

const MyApp = React.lazy(() =>
  loadModule(
    'http://localhost:3001/remoteEntry.js',
    'app1',
    './MyApp',
  ),
);

For further details, you can refer to the Webpack 5 documentation.

Solution 2:[2]

 new ModuleFederationPlugin({
    name: 'reactParent',
    filename: 'remoteEntry.js',
    remotes: {
        reactChild: 'reactChild@/reactChild/remoteEntry.js',
        svelteChild: 'svelteChild@/svelteChild/remoteEntry.js',
        vueChild: 'vueChild@/vueChild/remoteEntry.js'
    }
})

Putting the paths to the remoteEntry.js files into your Webpack config gets the job done. In this example, my app is setup to proxy requests to the micro-frontends, so /reactChild is proxied to where the particular app is running.

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 evalarezo
Solution 2 craigmiller160