Micro Frontends with Webpack 5 Module Federation and React
“Micro frontend” is a frontend application architecture inspired by micro-services, in which the app is decomposed into different “micro” applications, allowing them to work loosely together and maintained by independent teams. In this blog, I’m going to focus on client-side runtime composed micro frontends with Webpack module federation plugin. If you’d rather to look at the code instead, find the final repo here.
There are 2 main types of micro frontends based on where the composition happens. More common build time composition and runtime composition. Each of them presents a set of unique advantages and challenges. Managing authentication/authorization, versioning and inter-communication between micro frontends become difficult by design compared to a monolith frontend so this architecture might not be the right fit for all applications/organizations. But thats a topic for another blog.
Setting up a micro frontend (remote)
This will be our micro frontend application. While you can have many of these, for this blog I’ll be creating only one. While you are free to use any frontend framework, or in fact a combination of different frameworks for different micro frontends. I’ll be using React.
1. Create a new project
npx create-react-app mfe1
Once that’s done, go to
mfe1 directory and open the project in a code editor.
2. Configure app to support dynamic imports
Create a new file in
src directory called
bootstrap.js and move the content of
src/index.js to newly created
bootstrap.js file. Import bootstrap file from
index.js with dynamic module import syntax.
3. Upgrade to Webpack 5
We need Webpack 5 to support module federation. As of July 2021,
create-react-app uses Webpack 4. Therefore we have to install dependancies and configure the build process ourselves.
I previously wrote a quick guide on converting a React project to Webpack 5. Follow that to convert your newly created app to Webpack 5. Find it here.
webpack.config.js file in root level
Now that we have Webpack 5, we need custom configuration to support module federation.
*** You might need to handle typescript, CSS pre/post processors and other optimizations based on your needs in your production configuration. I just want to highlight the
ModuleFederationPlugin usage on line 38 ***
Now you should be able to run the application with
Setting up the host app (container)
1. Create a new project
npx create-react-app container
The next steps are similar to how we configured the micro frontend. You have to configure the host app to support dynamic imports, upgrade to Webpack 5 and configure
babel.config.json. Follow the steps 2,3 and 4 of “Setting up a micro frontend” section. Don’t forget to change the port number in webpack.config.js and package.json from 3001 to something else, I’m going to choose port 3000.
Now you should have 2 identical React projects that use Webpack 5, running on port 3000 (host) and 3001(remote).
Share component(s) from micro frontend
Our goal is to render the micro frontend inside the host app in runtime. I’ve changed
App.js file in
mfe1 project so that we can differentiate host and remote apps.
We also need to change
webpack.config.js file in
mfe1 to expose the
exposes property of options object that you pass to
ModuleFederationPlugin which was previously empty, now has a value. It basically tells Webpack that we are planing to use this module in a different application. You are free to expose as many components as you prefer similarly.
Consume micro frontend(s) from Host
Now that we exposed a component from our micro frontend, we need to configure the host app’s
webpack.config.js to make use of it on runtime.
remotes property of
ModuleFederationPlugin options object. That tells Webpack that we are planning to consume a remote module thats running on
mfe should match the
name you passed to
ModuleFederationPlugin in the remote app.
Finally we just have to load this component in the host app.
If you followed this guide so far and everything went well, your host app should render the micro frontend inside the host application.
If you open chrome dev tools, you should see that the micro frontend is actually coming from
localhost:3001 But rendered on the host app running on
Pretty neat! Your setup uses Module Federation with Webpack 5. Find the final repo here.
Shoutout to Webpack team for building amazing tools and continuously improving them. Often times the frontend frameworks get way too much credit but tools like Webpack do the heavy lifting behind the scenes!