6

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

2 Answers 2

5

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.

Sign up to request clarification or add additional context in comments.

Comments

-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.

1 Comment

How is this lazy loading?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.