Microfrontend with Module Federation
Introduction
In a previous article, I provided guidance on using Vite to set up a React project integrated with Micro Frontend. However, you may have noticed that during development, you need to rebuild the static files for the exposed components in the Remote App before they can be used in the Shell App. To address this issue and improve development performance, in this article, I will guide you on how to use Module Federation to implement Micro Frontend. First, let’s explore some concepts about Module Federation.
What is Module Federation?
Module Federation is an architectural pattern for decentralizing JavaScript applications (similar to microservices on the server-side). It allows you to share code and resources among multiple JavaScript applications (or micro-frontends). This can help you:
- Reduce code duplication
- Improve code maintainability
- Lower the overall size of your applications
- Enhance the performance of your applications
What is Module Federation 2.0?
Module Federation 2.0 differs from the original Module Federation built into Webpack 5 by not only providing the core features of module export, loading, and dependency sharing but also additional features like dynamic type hinting, Manifest, Federation Runtime, and Runtime Plugin System. These features make Module Federation more suitable for use as a micro-frontend architecture in large-scale web applications.
Prerequisites
- Module Federation requires NodeJS version >= 16, and it's recommended to use the LTS version of NodeJS 20.
- Check out the article on using Vite to set up a React Micro Frontend project to familiarize yourself with some basic concepts beforehand.
Implementation Steps
Similar to the previous article, to set up a Micro Frontend, you will need a Host app and a Remote app. Use the following command to create two corresponding projects: `shell-app` and `remote-app`.
Rspack
- Rspack is a high-performance web construction tool based on Rust, with interoperability with the webpack ecosystem. It can be integrated into webpack projects at a low cost and offers better build performance.
- Compared to webpack, Rspack has significantly improved build performance, thanks to the language advantages brought by Rust, as well as its parallel architecture and incremental compilation features. Benchmark tests have shown that Rspack can bring a 5 to 10 times increase in compilation performance.
Rsbuild
- Rsbuild is a web construction tool based on Rspack, with the following features:Rsbuild is an enhanced version of the Rspack CLI, more user-friendly and ready out of the box.
- Rsbuild represents the Rspack team's exploration and implementation of best practices for web construction.
- Rsbuild is the best solution for migrating Webpack applications to Rspack, reducing configuration by 90% and speeding up builds by 10 times.
Then add the following package to each project
This is the core package of Module Federation, serving as a Webpack build plugin, Rspack build plugin, and Runtime entry dependency.
The next step is to create a file named bootstrap.tsx and copy the content from App.tsx into it. After that, modify the content of the index.tsx file as follows (perform this for both projects):
The next step in your remote-app project is to create a file named Button.tsx with the following content:
Update the App.tsx file to use the Button
Update the config of the file `rsbuild.config.ts`
You can see that the configuration is similar to when using Vite. It also requires a unique name, exposes the Button component for use in the Shell app, and defines shared modules as react and react-dom.
Let's start the remote-app and take a look
Next, in the shell-app project, modify the `tsconfig.json` file as follows to create a module alias for the remote modules:
This way, Module Federation will auto-generate the corresponding type file (.d.ts) for the remote module to use in the TypeScript project.
Update the file `rsbuild.config.ts` as follows
The configuration is quite similar to `remote-app`, with the addition of the `remotes` field used to define the remote module. You should replace it with the correct name of the remote module and the port defined in `remote-app`.
Modify `App.tsx` to use the remote module Button as follows:
The result is that when you change the content of the Button.tsx file in remote-app, you only need to reload to see the corresponding update in shell-app.
Dynamic import
Dynamic import is an essential feature in any large web application, and when using Micro Frontend with Module Federation, there are two ways to implement it as follows:1. Using `import`
First, create the file `function1.ts` in the remote app as follows:Next, update the `rsbuild.config.ts` file to expose this module.
Then, to use it in the shell-app within the App.tsx file, you can implement it as follows:
2. Federation runtime
Using this method, there's no need to define which remote modules to use in the `rsbuild.config.ts`. Instead, the initialization and loading of remote modules can be handled flexibly according to custom logic.
First, create an additional project named `function` (similarly to how the `remote-app` project was created, as I explained earlier, including creating the `bootstrap.tsx` file, etc.).
Next, create the `function2.ts` file.
Then update the `rsbuild.config.ts` file to expose the module as follows:
Finally, update the App.tsx file in the shell-app to use remote modules.
You can see that method 2 will use the `init` function to register the remote module (this way, you no longer need to define remotes in the `rsbuild.config.ts` file), and then use the `loadRemote` function to load the required module.
As a result, the corresponding module will only be loaded to execute the function when you click on a button.
Comments
Post a Comment