Microfrontends Made Easy: A Practical Guide for React Developers

Microfrontends Made Easy: A Practical Guide for React Developers

by Ibimina H.

If you think managing complex frontend applications is a daunting task, you’re not alone. Many developers are finding monolithic architectures inadequate for today’s fast-paced development landscape, struggling with issues of scalability and team collaboration. Microfrontends offer a game-changing solution by breaking down applications into independent modules that can be developed and deployed without interference. In this article, we’ll explore how to implement microfrontends using React and modern tools like Webpack Module Federation, equipping you with the knowledge to enhance your projects’ scalability and maintainability.

What Are Microfrontends?

Microfrontends extend the principles of microservices to the frontend, enabling teams to work on different features independently. These individual frontend modules can be built using different frameworks, deployed separately, and seamlessly integrated into a single user interface.

Key Benefits of Microfrontends

  • Scalability: Independent scaling of frontend modules based on demand.
  • Flexibility: Teams can choose different frameworks or libraries for different parts of the application without dependencies on each other.
  • Faster Development: Parallel development by smaller, focused teams.
  • Incremental Upgrades: Easier to update or replace specific parts of the UI without impacting the entire application.
  • Independent Deployment: Modules can be deployed without redeploying the entire application.

Implementing Microfrontends with React and Webpack Module Federation

One of the most popular tools for implementing microfrontends is Webpack Module Federation. It allows you to dynamically load and share code between multiple applications at runtime. Let’s walk through a practical example.

Step 1: Setting Up the Project Structure

We’ll create two React applications:

Host Application: The main application that integrates multiple microfrontends.

Remote Application: A microfrontend that provides a specific feature (e.g., a dashboard).

Install Dependencies

npm install webpack webpack-cli webpack-dev-server html-webpack-plugin webpack-merge babel-loader --save-dev
npm install react react-dom        

First, ensure you have Webpack and React installed in both applications:

Step 2: Configuring Webpack Module Federation

Remote Application Configuration

In the remote application, configure Webpack to expose a component (e.g., a Dashboard):

const { ModuleFederationPlugin } = require("webpack").container;
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");


module.exports = (_, argv) => ({
  entry: "./src/index.js",
  output: {
    path: path.resolve(__dirname, "build"),
    publicPath: argv.mode === 'development' ? `https://localhost:3001/` : 'replace with live url for remote application',
  },
  devServer: {
    port: 3001,
  },
  resolve: {
    extensions: [".jsx", ".js", ".json"],
  },
    module: {
        rules: [
            {
                test: /\.(js|jsx)$/, // or /\.(ts|tsx)$/ if using TypeScript
                exclude: /node_modules/,
                use: {
                    loader: "babel-loader",
                    options: {
                        presets: ["@babel/preset-env", "@babel/preset-react"],
                    },
                },
            },
            {
                test: /\.svg$/,
                oneOf: [
                    {
                        resourceQuery: /component/, // Use "?component" in import to load as React component
                        use: ["@svgr/webpack"],
                    },
                    {
                        use: {
                            loader: "file-loader",
                            options: {
                                name: "[name].[hash].[ext]",
                                outputPath: "assets", // Save inside "dist/assets/"
                            },
                        },
                    },
                ],
            },
            {
                test: /\.css$/,
                use: ["style-loader", "css-loader"],
            },
        ],
    },    
  plugins: [
    new ModuleFederationPlugin({
      name: "remote",
      filename: "remoteEntry.js",
      exposes: {
        "./App": "./src/App",  // Exposing the Microfrontend's App component
      },
      shared: {
        react: { singleton: true, eager: true },
        'react-dom': { singleton: true, eager: true },
      },
    }),
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
  ],
});        

Host Application Configuration

In the host application, configure Webpack to consume the remote module:

const { ModuleFederationPlugin } = require("webpack").container;
const HtmlWebpackPlugin = require("html-webpack-plugin");
const path = require("path");


module.exports = (_, argv) => ({
  entry: "./src/index.js",
  output: {
  path: path.resolve(__dirname, "build"), 
    publicPath:
      argv.mode === "development"
        ? `https://localhost:3000/`
        : "replace with live url for host application",
  },
  devServer: {
    port: 3000,
  },
  resolve: {
    extensions: [".jsx", ".js", ".json"],
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/, // or /\.(ts|tsx)$/ if using TypeScript
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env", "@babel/preset-react"],
          },
        },
      },
      {
        test: /\.svg$/,
        oneOf: [
          {
            resourceQuery: /component/, // Use "?component" in import to load as React component
            use: ["@svgr/webpack"],
          },
          {
            use: {
              loader: "file-loader",
              options: {
                name: "[name].[hash].[ext]",
                outputPath: "assets", // Save inside "dist/assets/"
              },
            },
          },
        ],
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
  plugins: [
    new ModuleFederationPlugin({
      name: "host",
      filename: "remoteEntry.js",
      remotes: {
       remote: `remote@replace with live url or local host for remote application/remoteEntry.js`,
      },
      shared: {
        react: { singleton: true, eager: true },
        "react-dom": { singleton: true, eager: true },
      },
    }),
    new HtmlWebpackPlugin({
      template: "./public/index.html",
    }),
  ],
});        

Update Script

Replace start and build script in both remote and host application package.json

"start": "webpack serve --config webpack.config.js --mode development",
"build": "webpack --config webpack.config.js --mode production",        

Step 3: Using the Remote Microfrontend in the Host Application

In the host application, dynamically import the remote module using React’s lazy and Suspense:

import './App.css';
import React, { Suspense } from "react";
// Importing the Microfrontend dynamically
const App = React.lazy(() => import("remote/App"));
function AppPage() {
  return (
    <div>
    <h1>Host Application</h1>
    <Suspense fallback={<div>Loading Microfrontend...</div>}>
      <App />
    </Suspense>
  </div>
  );
}


export default AppPage;        

Step 4: Running the Applications

Start both applications:

cd remote && npm start
cd host && npm start        

Step 5: Deploy the Applications to GitHub

Push Your Applications to GitHub Initialize a git repository

git init        

?Commit and push to Github

git add .
git commit -m "Initial commit"
git branch -M main
git remote add origin https://github.com/your-username/your-repo-name.git
git push -u origin main        

Step 6: Deploy to Vercel

Sign Up/Log In to Vercel:

Go to Vercel and sign up or log in using your GitHub account.

Create a New Project:

Click on New Project.

Select the GitHub repository where your microfrontend code is hosted.

Configure the Build Settings:

Vercel will automatically detect your React application and configure the build settings.

For the remote application, repeat the same steps in a separate Vercel project.

Deploy:

Click Deploy to start the deployment process.

Vercel will build and deploy your application, providing you with a live URL.

Step 7: Update Remote Application URL

After deploying the remote application, update the remoteEntry.js URL in the host application:

Get the Remote Application URL:

Once the remote application is deployed, Vercel will provide a live URL (e.g., https://remote-app.vercel.app).

Update Webpack Configuration:

In the host application, update the remotes configuration in webpack.config.js:

remotes: {

??remote: "remote@https://remote-app.vercel.app/remoteEntry.js",

},

Redeploy the Host Application:

Push the changes to GitHub, and Vercel will automatically redeploy the host application.

Conclusion

Microfrontends represent a transformative shift in frontend development, allowing teams to operate with greater autonomy and agility. The integration of Webpack Module Federation has proven that incorporating a React-based microfrontend into existing applications is not just feasible but also advantageous. As we witness the rising trend of microfrontends, we can expect continuous improvements from tools like Webpack 5 and frameworks such as Single-Spa, which will further streamline the development process. By adopting this modular architecture, developers are empowered to create applications that are not only scalable but also easier to maintain and adapt over time. Whether you’re working on a large-scale enterprise application or a modular project, microfrontends provide a pathway to efficient and collaborative development.

要查看或添加评论,请登录

Cecure Intelligence Limited的更多文章