Mastering Micro-Frontends with Module Federation in React: A Complete Guide

In the ever-evolving world of web development, creating scalable, maintainable, and modular applications is crucial. Micro-frontend architecture has emerged as a solution to manage large-scale applications by breaking them into smaller, manageable pieces. One of the groundbreaking techniques to implement this architecture in React is using Module Federation introduced in Webpack 5.

In this blog post, we will explore how to unlock seamless micro-frontend architecture with Module Federation, complete with examples to guide you through the process.

What is Micro-Frontend Architecture?

Micro-frontend architecture is an extension of microservices to the frontend world. It allows large applications to be divided into smaller, independent fragments, each developed, tested, and deployed independently. These fragments can be composed to form a cohesive user experience.

Module Federation

Module Federation is a feature in Webpack 5 that allows multiple separate builds to form a single application. It enables the sharing of code and dependencies between these builds at runtime, making it a perfect fit for micro-frontends.

Related read: Building Scalable Applications with React Micro Frontends

Setting Up Your Environment

Before we dive into examples, let’s set up a basic environment:

1. Install Node.js: Ensure you have Node.js installed.

2. Create React Apps: Use create-react-app to set up two React applications. We will name them host-app and remote-app.

npx create-react-app host-app
npx create-react-app remote-app

3. Install Webpack 5: Upgrade both applications to use Webpack 5.

cd host-app
npm install webpack@5 webpack-cli html-webpack-plugin --save-dev
cd ../remote-app
npm install webpack@5 webpack-cli html-webpack-plugin --save-dev

Configuring Module Federation

Step 1: Configure remote-app

🔺Create Webpack Configuration: In the remote-app directory, create webpack.config.js.

const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin;

module.exports = {
  entry: './src/index',
  mode: 'development',
  devServer: {
    contentBase: './dist',
},
output: {
  publicPath: 'http://localhost:3001/',
},
module: {
  rules: [
    {
       test: /\.jsx?$/,
       loader: 'babel-loader',
       exclude: /node_modules/,
    },
  ],
},
plugins: [
  new HtmlWebpackPlugin({
    template: './public/index.html',
  }),
  new ModuleFederationPlugin({
    name: 'remoteApp',
    filename: 'remoteEntry.js',
    exposes: {
      './Button': './src/Button',
    },  
  }),
 ],
};

🔺Create a Component: In remote-app/src, create Button.jsx.

import React from 'react';

const Button = () => {
  return <button>Remote Button</button>;
};

export default Button;

🔺Start the Application: Update scripts in package.json and start the application.

"scripts": {
 "start": "webpack serve --mode development"
}

Step 2: Configure host-app

🔺Create Webpack Configuration: In the host-app directory, create webpack.config.js.

const HtmlWebpackPlugin = require('html-webpack-plugin');
const ModuleFederationPlugin = require('webpack').container.ModuleFederationPlugin;


module.exports = {
  entry: './src/index',
  mode: 'development',
  devServer: {
    contentBase: './dist',
  },
output: {
  publicPath: 'http://localhost:3000/',
},
module: {
   rules: [
     {
        test: /\.jsx?$/,
        loader: 'babel-loader',
        exclude: /node_modules/,
     },
  ],
},
plugins: [
  new HtmlWebpackPlugin({
    template: './public/index.html',
  }),
new ModuleFederationPlugin({
   name: 'hostApp',
   remotes: {
     remoteApp: 'remoteApp@http://localhost:3001/remoteEntry.js',
   },
  }),
 ],
};

🔺Import Remote Component: In host-app/src, update App.jsx.

import React, { Suspense, lazy } from 'react';
const RemoteButton = lazy(() => import('remoteApp/Button'));

function App() {
  return (
   <div className="App">
     <h1>Host Application</h1>
     <Suspense fallback={<div>Loading...</div>}>
       <RemoteButton />
     </Suspense>
   </div>
 );
}

export default App;

🔺Start the Application: Update scripts in package.json and start the application.

"scripts": {
 "start": "webpack serve --mode development"
}

Start Building Scalable React Apps Today!

Running the Applications

Start both applications:

cd remote-app
npm start
cd ../host-app
npm start

Navigate to http://localhost:3000 to see the host application loading the remote component.

Benefits of Module Federation in Micro-Frontend Architecture

  1. Independence: Each micro-frontend can be developed and deployed independently.
  2. Scalability: Easier to scale development teams by dividing the work into smaller chunks.
  3. Shared Code: Common libraries and components can be shared, reducing redundancy.
  4. Incremental Upgrades: Allows gradual updates and migrations.
coma

Conclusion

Module Federation in Webpack 5 revolutionizes the way we build and manage micro-frontend architectures. By enabling seamless sharing of code and dependencies between independent applications, it unlocks a new level of flexibility and efficiency. With this guide, you now have the foundational knowledge to start implementing Module Federation in your projects.

Happy coding!

Keep Reading

Keep Reading

Enhance Your Epic EHR Expertise in Just 60 Minutes!

Register Here
  • Service
  • Career
  • Let's create something together!

  • We’re looking for the best. Are you in?