Building Micro-Frontends with Module Federation

Reading Time: 7 min read

Introduction

As web applications grow in complexity, managing a monolithic codebase becomes increasingly challenging. Micro-frontends offer a solution by allowing teams to develop and deploy features independently, leading to better scalability and maintainability. Module Federation, introduced in Webpack 5, is a powerful tool for implementing micro-frontends. In this post, we'll explore how to use Module Federation to build scalable and maintainable micro-frontends in your web applications.

What is Module Federation?

Module Federation is a feature in Webpack 5 that allows multiple independent builds to work together, sharing code and dependencies at runtime. This enables the development of micro-frontends, where different parts of a web application can be developed and deployed separately, yet work seamlessly together.

Setting Up Module Federation

  1. Install Webpack 5:

    Ensure your project is using Webpack 5. If not, install or upgrade to Webpack 5:

    npm install webpack@5 webpack-cli --save-dev
  2. Configure Module Federation:

    Configure the webpack.config.js file to set up Module Federation. For this example, we'll create two micro-frontends: app1 and app2.

    // app1/webpack.config.js
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const ModuleFederationPlugin =
      require('webpack').container.ModuleFederationPlugin
     
    module.exports = {
      entry: './src/index.js',
      mode: 'development',
      devServer: {
        contentBase: './dist',
      },
      output: {
        publicPath: 'http://localhost:3001/',
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.html',
        }),
        new ModuleFederationPlugin({
          name: 'app1',
          filename: 'remoteEntry.js',
          exposes: {
            './Button': './src/Button',
          },
          shared: ['react', 'react-dom'],
        }),
      ],
    }
    // app2/webpack.config.js
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const ModuleFederationPlugin =
      require('webpack').container.ModuleFederationPlugin
     
    module.exports = {
      entry: './src/index.js',
      mode: 'development',
      devServer: {
        contentBase: './dist',
      },
      output: {
        publicPath: 'http://localhost:3002/',
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: './src/index.html',
        }),
        new ModuleFederationPlugin({
          name: 'app2',
          remotes: {
            app1: 'app1@http://localhost:3001/remoteEntry.js',
          },
          shared: ['react', 'react-dom'],
        }),
      ],
    }

Creating Micro-Frontends

  1. Exposing Components in app1:

    In app1, create a simple Button component to expose.

    // app1/src/Button.js
    import React from 'react'
     
    const Button = () => {
      return <button>Button from App 1</button>
    }
     
    export default Button
  2. Consuming Components in app2:

    In app2, consume the exposed Button component from app1.

    // app2/src/App.js
    import React from 'react'
    const Button = React.lazy(() => import('app1/Button'))
     
    const App = () => {
      return (
        <div>
          <h1>App 2</h1>
          <React.Suspense fallback="Loading Button...">
            <Button />
          </React.Suspense>
        </div>
      )
    }
     
    export default App

Running the Micro-Frontends

  1. Start the Development Servers:

    Start the development servers for both app1 and app2.

    # In app1
    npm start
     
    # In app2
    npm start

    Open http://localhost:3002 in your browser to see app2 consuming the Button component from app1.

Benefits of Using Module Federation

  1. Independent Deployment:

    • Teams can deploy micro-frontends independently without affecting other parts of the application.
  2. Scalability:

    • Micro-frontends allow large applications to scale efficiently by dividing the workload among multiple teams.
  3. Code Sharing:

    • Module Federation enables sharing of code and dependencies between micro-frontends, reducing duplication and improving maintainability.

Conclusion

Module Federation in Webpack 5 provides a powerful way to build micro-frontends, enabling independent development and deployment of different parts of a web application. By leveraging Module Federation, you can create scalable, maintainable, and efficient applications that meet the demands of modern web development.

For more detailed information, visit the Webpack Module Federation documentation.

Go back Home.