Micro Frontends Step by Step Using React, Webpack 5, and Module Federation With Deployment to AWS
Micro Frontends With a Hands-On Example Using React, Webpack 5, and Module Federation

Micro Frontends Step by Step Using React, Webpack 5, and Module Federation With Deployment to AWS

In this article, I will go step by step in creating two Micro Frontend React Components and render a Button component from one into the other. At the end of this article, you will be able to implement a microfrontend component and render it into a microfrontend container, then deploy it to AWS with a secured domain. The final result can be seen at https://mfe1.microfrontends.info/

No alt text provided for this image

If you are new to Microfrontend, you may start with the following article:


This hands-on example is a continuation to the following two articles where I explained how Micro Frontends work with Webpack5 and Module Federation. I wanted to give clean steps on React components without all the explanations. Please, refer to those articles for explanations



The final project can be found at https://github.com/ranyelhousieny/react-microfrontends

Video for the project at

==========================


1. Create two React apps and install dependencies

npx create-react-app mfe1

cd mfe1

yarn add webpack webpack-cli webpack-server html-webpack-plugin babel-loader webpack-dev-server
        
No alt text provided for this image


npx create-react-app mfe2

cd mfe2


yarn add webpack webpack-cli webpack-server html-webpack-plugin babel-loader webpack-dev-server
        

Note: While I used create-react-app here for an easier walkthrough, I will not depend on it at all and we will create our own webpack.config.js. You may learn how to set up a React project without CRA in this article


2. In both Apps, rename index.js to bootstrap.js

in bootstrap.js, Remove the imports to index.css and reportWebVitals and keep the file as shown below:

import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';


ReactDOM.render(
  <App />,
  document.getElementById(
    'root'
  )
);
        

Here are the files on Github

https://github.com/ranyelhousieny/react-microfrontends/blob/main/mfe1/src/bootstrap.js

We do this step to make bootstrap load asynchronously. It is needed for MFE2 to wait for Webpack to fetch components from MFE1.

3. In both Apps, create a new index.js that has one line

import('./bootstrap');
        

Here is the file on Github

https://github.com/ranyelhousieny/react-microfrontends/blob/main/mfe1/src/index.js


4. In MFE1, Create. a Button component

Create a file src/Button.js

Copy inside it this code (It is a very simple component)

import React from 'react';


const Button = () => (
  <button>MFE1 Button</button>
);


export default Button;
        

Code can be found at

https://github.com/ranyelhousieny/react-microfrontends/blob/main/mfe1/src/Button.js

4.1. In MFE1, update App.js as?follows

No alt text provided for this image


Code can be found at https://github.com/ranyelhousieny/react-microfrontends/blob/main/mfe1/src/App.js


5. In MFE1, Create a Webpack.config.js on the root and put the following inside it

(details about this file and building it step by step can be found?here ?https://www.dhirubhai.net/pulse/understanding-micro-frontends-webpack5-configurations-rany/ ?and the video?https://youtu.be/AZDDIgJSKU0 )

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


module.exports = {
  mode: 'development',
  devServer: {
    port: 8083,
  },
  module: {
    rules: [
      {
        /* The following line to ask babel 
             to compile any file with extension
             .js */
        test: /\.js?$/,


        /* exclude node_modules directory from babel. 
            Babel will not compile any files in this directory*/
        exclude: /node_modules/,


        // To Use babel Loader
        loader:
          'babel-loader',
        options: {
          presets: [
            '@babel/preset-env' /* to transfer any advansed ES to ES5 */,
            '@babel/preset-react',
          ], // to compile react to ES5
        },
      },
    ],
  },


  plugins: [
    new ModuleFederationPlugin(
      {
        name: 'MFE1',
        filename:
          'remoteEntry.js',


        exposes: {
          './Button':
            './src/Button',
        },
      }
    ),
    new HtmlWebpackPlugin({
      template:
        './public/index.html',
    }),
  ],
};
        

https://github.com/ranyelhousieny/react-microfrontends/blob/main/mfe1/webpack.config.js

Here we created MFE1 and made it expose the Button Component through https://localhost:8083/remoteEntry.js. Webpack renders this on https://localhost:8083.

No alt text provided for this image




6. In MFE2, Create a Webpack.config.js on the root and put the following inside it

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


module.exports = {
  mode: 'development',
  devServer: {
    port: 8082,
  },
  module: {
    rules: [
      {
        /* The following line to ask babel 
             to compile any file with extension
             .js */
        test: /\.js?$/,


        /* exclude node_modules directory from babel. 
            Babel will not compile any files in this directory*/
        exclude: /node_modules/,


        // To Use babel Loader
        loader:
          'babel-loader',
        options: {
          presets: [
            '@babel/preset-env' /* to transfer any advansed ES to ES5 */,
            '@babel/preset-react',
          ], // to compile react to ES5
        },
      },
    ],
  },


  plugins: [
    new ModuleFederationPlugin(
      {
        name: 'MFE2',
        filename:
          'remoteEntry.js',
        remotes: {
          MFE1:
            'MFE1@https://localhost:8083/remoteEntry.js',
        },
      }
    ),
    new HtmlWebpackPlugin({
      template:
        './public/index.html',
    }),
  ],
};
        

https://github.com/ranyelhousieny/react-microfrontends/blob/main/mfe2/webpack.config.js

No alt text provided for this image

Here we just said that MFE1 exposed components can be available in MFE2 remotely through https://localhost:8083/remoteEntry.js

7. In MFE2 src/App.js import Button (Lazy import)

const MFE1_Button = React.lazy(
  () => import('MFE1/Button')
);
        

Add it to the App as follows

function App() {
  return (
    <div>
      <h1>MFE2</h1>
      <div>
        <React.Suspense fallback='Loading Button'>
          <MFE1_Button />
        </React.Suspense>
      </div>
      <h2>MFE2</h2>
    </div>
  );
}
        

open a terminal inside MFE1 directory and run

yarn webpack serve        

Do the same on MFE2 directory

Now open the browser and navigate to

https://localhost:8082/

You should see the following

No alt text provided for this image
No alt text provided for this image


==============================

Explanation:

Now, let's take a step back and understand what we have done.

First: Webpack created two servers for us

  1. MFE1 on https://localhost:8083/ [We decided this port in the configuration]

No alt text provided for this image


  1. MFE2 on https://localhost:8082/

No alt text provided for this image

Second: Using Module Federation Plugin we exposed the Button component from MFE1 site (https://localhost:8083/) and imported it into MFE2

No alt text provided for this image

Here is the configuration that did that

No alt text provided for this image

=======================

Deploying Microfrontends

After we implemented and tested the Microfrontends locally, let's deploy them to AWS. Follow the steps in the following article to deploy to AWS:

You can browse the deployed version at https://mfe1.s3-website-us-east-1.amazonaws.com/

No alt text provided for this image

If you click inspect and then Network as shown above, you can see the call to get https://rany.tk/mfe/mfe1/dist/remoteEntry.js

Now, we created a host and added a microfrontend inside it then we deployed to AWS.

========================================

Add AWS CloudFront

after deploying to S3, let's add CloudFront for caching, security, and to add a domain name. This is a very important step when deploying a website. Follow the following article to add CloudFront

Now, you can access MFE2 from the following Link https://d1tsn16diydefl.cloudfront.net/

No alt text provided for this image

=====================================

Purchasing and Adding a Domain name:

Now, it is very hard to memorize the previous link https://d1tsn16diydefl.cloudfront.net/ . In the following article I will go step by step to purchase microfrontends.info and render the site to https://mfe1.microfrontends.info/

No alt text provided for this image




Other Micro Frontend articles at:


ganesh kumar gupta

NodeJs, ExpressJs, ReactJs, PostgreSQL-FULL STACK DEVELOPER

1 年

this artical not complete support. I will give you 2 star

回复
Mikhail Soosaar

Programmer at FizzDev

3 年

Hello! I'm a bit stuck with this article. I can't understand how to use my modules in container app? Can you give some explanations with this?

回复

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

社区洞察

其他会员也浏览了