Micro Frontends with Webpack 5 Module Federation and React

Harshana Abeyaratne
5 min readJul 25, 2021

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

Demo

Remote app is running at https://happy-scarecrow.surge.sh/
Host app is at http://madly-driving.surge.sh/

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.

import() is the syntax for dynamic module imports. Read more here: https://2ality.com/2017/01/import-operator.html

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.

4. Create 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 yarn start

Setting up the host app (container)

1. Create a new project

Your host and micro frontends either can live in a monorepo (with something like Lerna) or separate repositories.

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 webpack.config.js, package.json and 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 App component.

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.

Notice the remotes property of ModuleFederationPlugin options object. That tells Webpack that we are planning to consume a remote module thats running on localhost:3001 Prefix 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 localhost:3000.

Pretty neat! Your setup uses Module Federation with Webpack 5. Find the final repo here.

Demo

Remote app is running at https://happy-scarecrow.surge.sh/
Host app is at http://madly-driving.surge.sh/

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!

Cheers!

--

--