Skip to content

chaitanyax/micro-frontend-example

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Micro Frontend Architecture with Webpack 5 Module Federation

This project demonstrates a Micro Frontend architecture using Webpack 5 Module Federation.

Architecture Overview

The architecture consists of three completely independent React applications:

  1. Shell App (Host) - port 3000: Functions as the main host container. It contains the main navigation and lazily loads the other micro frontend applications at runtime.
  2. Profile App (Remote) - port 3001: A remote standalone app that exposes a ProfileComponent.
  3. Marketplace App (Remote) - port 3002: A remote standalone app that exposes a MarketplaceComponent.

Key Features Checklist

  • Webpack 5 Module Federation Plugin.
  • Three independent apps with a clear, separate folder structure (shell, profile, marketplace).
  • Apps are independently developable, deployable, and versionable.
  • Lazily loading of remote components ProfileComponent & MarketplaceComponent using React lazy and Suspense.
  • Simple navigation UI in the Shell App using React Router framework to switch views.
  • Dynamic Resolution: remoteEntry.js URLs are NOT hardcoded in the webpack configuration. They are resolved via an environment configuration file (config.json), read at bootstrap time.
  • Graceful Failover: Implementing React ErrorBoundary specifically designed to handle network failures when lazy loading chunks.
  • Both standard app running and isolated running are supported (both modules expose components but also render themselves out via bootstrap.js in case of isolated development).

Setup & Running the Project

Prerequisites

Make sure node and npm are installed.

1. Install Dependencies

Each app (shell, profile, marketplace) is a separate project, but you can set up everything simply by running install at the root level if you modify package.json with Workspaces. For this repository, simply run npm run install or since we have initialized them manually, dependencies are already installed. Note that concurrently has been configured to run them all at once.

If you are cloning this repository for the first time, run:

npm install concurrently -D

cd shell && npm install
cd ../profile && npm install
cd ../marketplace && npm install
cd ..

2. Start all applications

From the root directory of the workspace, run:

npm start

This command utilizes concurrently to start the development servers for all 3 apps simultaneously. Wait for the servers to compile.

3. Verification

  • Shell App: http://localhost:3000
    • Upon initial load, it will fetch /config.json, which points to the remote entries.
    • In the Network tab, you will initially only see Shell chunks.
    • Clicking Profile will dynamically trigger a network request for http://localhost:3001/remoteEntry.js and subsequently load the Profile chunk.
    • Clicking Marketplace lazy-loads the Marketplace chunk identically format.
  • Profile App (Standalone): http://localhost:3001
  • Marketplace App (Standalone): http://localhost:3002

Explanations on Dynamic Remote Resolution

Usually, remotes are hardcoded into webpack.config.js:

remotes: {
  profile: 'profile@http://localhost:3001/remoteEntry.js'
}

This prevents environment switching (dev -> staging -> prod) without rebuilding the Docker container / code.

Our Solution

Instead of hardcoding, we use Promises inside Webpack Config:

  1. At runtime before the application bootstraps (src/index.js), we execute an HTTP fetch() request to /config.json.
  2. This config.json stores the raw URLs:
{
  "profile": "http://localhost:3001/remoteEntry.js",
  "marketplace": "http://localhost:3002/remoteEntry.js"
}
  1. These URLs are stored inside window.__MF_REMOTES__.
  2. Our webpack.config.js consumes this global variable and synchronously injects the corresponding <script> tag dynamically using Promises when the specific remote bundle is actually triggered by React via User Navigation.
  3. Furthermore, any failure correctly triggers script.onerror() capturing the Promise rejection, eventually forwarding the failure state directly over to our <ErrorBoundary /> ensuring the host does not crash from missing remotes!

About

This project demonstrates a Micro Frontend architecture using Webpack 5 Module Federation.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors