Micro frontends with Module Federation in React Application

Micro frontends with Module Federation | Micro frontends architecture react | micro frontend react | module federation micro frontend react | module federation micro frontend | module federation react | module federation examples | module federation react example
π‘ What are Micro Frontends?
Micro front-end extends the concepts of microservices
to the frontend world. Building a feature-rich, potent browser application, often known as a single-page app, that rests on top of a microservice architecture is now popular.
Using Micro Frontends, you can think of a website or web app as a collection of features owned by independent teams. Each team has a distinct area of business or mission it cares about and specializes in. A team is cross-functional and develops its features end-to-end, from database to user interface.
Over the past few years, IT companies have begun to break large software into smaller, easier-to-manage chunks. In this approach, many services can be developed, tested, and deployed independently. Each of them will then be implementable by different frontend teams, and even with different technologies. This ensures the same scalability, flexibility, and adaptability that comes with the backend microservice architecture.
π‘ Benefits of Choosing Micro Frontends Today
- Scaling up to multiple teams
- Adopting different technical stack
- Development and deployment become faster
- It makes your web application more maintainable
- Support code and style isolation.
- The testing becomes very simple.
- No need to touch the entire application for every small change.
π‘ What is Module Federation?
The implementation of the micro front-end concept at the frontend side required a lot of tricks in the past. Fortunately, Module Federation makes this task straightforward. Module Federation
allows loading Micro Frontends at runtime. It is a JavaScript architecture invented by Zack Jackson
. This architecture allows the sharing of code and dependencies between two different application codebases.
Module Federation is an integrated part of webpack 5, and hence, it works with all modern web frameworks. Module Federation defines two roles: the host
and the remote
– to allow the loading of separately compiled and deployed micro frontends.
Module Federation plugin comes by default with Webpack 5 and we can easily import this with the below statement –
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
Lets implement Module Federation plugin in React application
Create Two React applications, We have given names here ApplicationOne and ApplicationTwo.

application-one is running on http://localhost:3000/
application-two is running on http://localhost:3001/
π» Later, in the same article, I will explain, how can we deploy applications on different – different ports?.
β application-one is the HOST
application that contains a Login Component which we will expose for others.
β application-two is a REMOTE
application that will consume Login Component from application-one.Note:
The most important file is webpack.config.js
where we will put all settings, loaders, rules, and plugins.
π‘ Install Webpack and html-webpack-plugin
Now Install the required Packages in both applications to work on Modular Federation.
> npm i webpack webpack-cli > npm i html-webpack-plugin "html-webpack-plugin": "^5.5.0", "webpack": "^5.73.0", // Please make sure, Webpack 5 is required for MF. "webpack-cli": "^4.10.0"
π‘ Loaders
We need to install loaders in both applications that are required for file transformations.
> npm install babel-loader css-loader style-loader "babel-loader": "^8.2.5", "css-loader": "^6.7.1", "style-loader": "^3.3.1",
π‘ babel preset packages
babel-loader also needs some other package to run the transformation. So to install those packages, run the below npm command in both apps.
> npm install @babel/core @babel/preset-env @babel/preset-react "@babel/core": "^7.18.6", "@babel/preset-env": "^7.18.6", "@babel/preset-react": "^7.18.6",
π‘ .babelrc
Now in both applications, Create a file named '.babelrc'
& put the below object inside that. Webpack will automatically read this file.
{ "presets": [ "@babel/preset-env", "@babel/preset-react" ] }
π‘ start and build command
In the Package.json file of each project, replace script: start and build with the below code.
"start": "webpack serve --open", "build": "webpack build"
π‘ bootstrap.js and index.js
In both applications rename index.js file to bootstrap.js
.
And then create a new index.js
file and import bootstrap.js file here with the below line.
> If we do not perform this step, you will get a below line of error.
π Uncaught Error: Shared module is not available for eager consumption: webpack/sharing/consume/default/react/react
import('./bootstrap.js')
webpack.config.js file of HOST application ‘application-one’
Create a Webpack.config.js on the root and put the following inside it.
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const deps = require('./package.json').dependencies; const path = require('path'); // object { exposes?, filename?, library?, name?, remoteType?, remotes?, runtime?, shareScope?, shared? } module.exports = { mode: 'development', devServer: { port: 3000, // App-one is running on port 3000 hot: false, liveReload: true, // enable live reload open: true, headers: { "Access-Control-Allow-Origin": "*", // for CORS }, }, resolve: { extensions: ['.js', '.jsx'] }, module: { rules: [{ test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, { test: /\.css$/i, use: ['style-loader', 'css-loader'], } ] }, plugins:[ new ModuleFederationPlugin({ name: 'applicationone', // HOST app name filename: 'remoteEntry.js', // remote file name remotes: { }, exposes: { './Login' : './src/components/Login.js', './bootstrapCss': 'bootstrap/dist/css/bootstrap.min.css' }, shared: { ...deps, react: { singleton: true, requiredVersion: deps.react, }, 'react-dom': { singleton: true, requiredVersion: deps['react-dom'] } } }), new HtmlWebpackPlugin({ template: path.resolve(__dirname, "public", "index.html")}) ] }
filename: 'remoteEntry.js',
filename is the main file generated with webpack cli that contains all shared and exposed items and is used in remote applications with the below line.
‘applicationone@http://localhost:3000/remoteEntry.js’
exposes: { './Login' : './src/components/Login.js', './bootstrapCss': 'bootstrap/dist/css/bootstrap.min.css' },
We have to use the Login component in another application so we exposed that component from the HOST application with expose
object.
Application-one Login component is using Bootstrap UI library, so we also need to expose that CSS to render styles.
shared: { ...deps, react: { singleton: true, requiredVersion: deps.react, }, 'react-dom': { singleton: true, requiredVersion: deps['react-dom'] } }
Exposed components are React components and depend on react and react-dom packages. That’s why we shared those packages as well with an shared
object like the above.
If you want to use Bootstrap UI Library
components as well in another application then you need to put those packages in a shared object like the below code.
'bootstrap' : { singleton: true, requiredVersion: deps['react-dom'] }, 'react-bootstrap' : { singleton: true, requiredVersion: deps['react-dom'] }
All set. Now run application-one by command > npm run start

REMOTE APP – webpack.config.js
Create webpack.config.js file in application-two at root lavel.
const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const deps = require('./package.json').dependencies; const path = require('path'); // object { exposes?, filename?, library?, name?, remoteType?, remotes?, runtime?, shareScope?, shared? } module.exports = { mode: 'development', devServer: { port: 3001, // here post is 3001 hot: false, liveReload: true }, resolve: { extensions: ['.js', '.jsx'] }, module: { rules: [{ test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader' } }, { test: /\.css$/i, use: ['style-loader', 'css-loader'], } ] }, plugins:[ new ModuleFederationPlugin({ name: 'applicationtwo', filename: 'remoteEntryapplicationtwo.js', remotes: { applicationone: 'applicationone@http://localhost:3000/remoteEntry.js', // HOST FILE path }, exposes: { }, shared: { ...deps, react: { singleton: true, requiredVersion: deps.react, }, 'react-dom': { singleton: true, requiredVersion: deps['react-dom'] } } }), new HtmlWebpackPlugin({ template: path.resolve(__dirname, "public", "index.html")}) ] }
remotes: { applicationone: 'applicationone@http://localhost:3000/remoteEntry.js', },
This is remote
object where we define remoteEntry.js
file of the HOST application.
You can check that file in the browser as well with the URL –
http://localhost:3000/remoteEntry.js
devServer: { port: 3001, // here post is 3001 hot: false, liveReload: true },
With the devServer object, we can define the port number where we have to run our application. We can set liveReload: true for auto-update changes in the browser.
All set for application-two. Now run application-two by command > npm run start

π‘ Sharing data between both applications
As Both applications are React applications so we can share data using props
.
So, here we will enter our email & password on the Login page And will show that in the application-two component after clicking on submit button.
Login Component of Application-One
This component will take data by props and will emit data with props.
import React, { useState } from 'react' import Button from 'react-bootstrap/Button'; import Form from 'react-bootstrap/Form'; export default function Login(props) { const [email, setmail] = useState(''); const [password, setPassword] = useState(''); const handleClick = () => { props.emitData({email, password}); } const onEmailChange = (e) => { setmail(e.target.value); } const onPasswordChange = (e) => { setPassword(e.target.value); } const styles = { marginTop: { marginTop: 20 }, box: { border: 'solid 1px gray', padding: 10 } } return ( <div className='container'> <h3>Login Page (From Application One)</h3> <Form style={styles.box}> <Form.Group classemail="mb-3" controlId="formBasicEmail"> <Form.Label>Email address</Form.Label> <Form.Control type="email" placeholder="Enter email" value={email} onChange={onEmailChange} /> <Form.Text classemail="text-muted"> We'll never share your email with anyone else. </Form.Text> </Form.Group> <Form.Group classemail="mb-3" controlId="formBasicPassword"> <Form.Label>Password</Form.Label> <Form.Control type="password" placeholder="Password" value={password} onChange={onPasswordChange} /> </Form.Group> <Button style={styles.marginTop} variant="primary" onClick={handleClick}> Submit </Button> </Form> </div> ) }
Order component of Application two
import React, { Suspense, useState } from 'react' const Login = React.lazy(() => import('applicationone/Login')) // Lazy load of host component export default function Order() { const [loginData, setLoginData] = useState(null); const receivedDataFromLogin = (value) => { setLoginData(value) } return ( <div>Order Component of application-two <Suspense fallback={<div>Something went wrong..</div>}> <Login emitData={receivedDataFromLogin}></Login> </Suspense> <div> { loginData ? <div style={{marginTop: 10}}> <div>You have entered below details (Fetching from Login Component - Application One)</div> <div>Your Email: {loginData.email}</div> <div> Your Password: {loginData.password}</div> </div> : '' } </div> </div> ) }
index.js file of application-two
We imported bootstrap css file of host app here.
import ('applicationone/bootstrapCss') import ('./bootstrap.js');

π‘ You can find the complete project on GitHub –
https://github.com/msaxena25/-msaxena25-Modular-Federation-React
Read here for webpack configs: https://webpack.js.org/concepts/module-federation/
- Insert node in Linked list | Algorithm | JavaScript
- Insertion Sort in data structure | Algorithm with Examples
- Selection Sort Algorithm & K’th Largest Element in Array
- Quick Sort Algorithm with example | Step-by-Step Guide
- Dependency Inversion Principle with Example | Solid Principles
- Object-Oriented Programming | Solid Principles with Examples
- ASCII Code of Characters | String Operations with ASCII Code
- Negative Binary Numbers & 2’s Complement | Easy explanation
- Factors of a Number | JavaScript Program | OptimizedΒ Way
- LeetCode – Game of Life Problem | Solution with JavaScript
- Fibonacci series using Recursion | While loop | ES6 Generator
- JavaScript Coding Interview Question & Answers
- LeetCode – Coin Change Problem | Dynamic Programming | JavaScript
- HackerRank Dictionaries and Maps Problem | Solution with JavaScript
- React Redux Unit Testing of Actions, Reducers, Middleware & Store
- Micro frontends with Module Federation in React Application
- React Interview Question & Answers – Mastering React
- Top React Interview Question & Answer | React Routing
- React Interview Questions and Answers | React hooks
- Higher Order Component with Functional Component | React JS
- Top React Interview Questions and Answers | Must Know
- Interview Question React | Basics for Freshers and Seniors
- Cyber Security Fundamental Questions & Answers You must know
- Application & Web Security Interview Questions & Answers
- Top Scrum Master and Agile Question & Answers 2022
- Trapping Rain Water Leetcode Problem Solution
- Array Representation of Binary Tree | Full Tree & Complete Binary Tree
- Graphs in Data Structure, Types & Traversal with BFS and DFS, Algorithms
- Traversing 2 D array with BFS & DFS Algorithm in JavaScript
- Time Complexity & Calculations | All You should know
Micro frontends with Module Federation | Micro frontends architecture react | micro frontend react | module federation micro frontend react | module federation micro frontend | module federation react | module federation examples | module federation react example