0% found this document useful (0 votes)
36 views21 pages

Webpack Module Federation in React

Uploaded by

patryk.klimowicz
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views21 pages

Webpack Module Federation in React

Uploaded by

patryk.klimowicz
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

Member-only story

How to Use Webpack Module Federation in


React
Build micro-frontend architectures with ease

Oskari Rautiainen · Follow


Published in Better Programming
5 min read · Jun 17, 2022

Listen Share More

Photo by Valery Fedotov on Unsplash

Module Federation is an excellent tool for constructing a micro-frontend


architecture in React applications. I will show you how to use it in a step-by-step
guide to building a Host-Remote pattern micro-frontend in React.

Why a Micro Frontend?

[Link] 1/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

Micro-frontends help us break large frontend applications into smaller independent


applications or modules that can be built and deployed at their cadence.

Doing this using Module Federation allows us to combine the applications at run
time in the client’s browsers and eliminate build-time dependencies and
coordination, allowing the teams building these applications to develop at scale.

Getting started
You can follow along with the final code found here: [Link]
micro-frontend-example

We are building two applications: host and remote .

The host app is the “main” app and remote is a sub-app plugging into it.

Module Federation does support treating the host as a remote and making the
architecture peer-to-peer if it fits your use case. More on this later.

We’re going to use create-react-app to simplify the initial steps.

In your root directory:

npx create-react-app host

npx create-react-app remote

This will create two apps for you:

host/

remote/

Dependencies
Within each host/ and remote/ run:

npm install --save-dev webpack webpack-cli html-webpack-plugin


webpack-dev-server babel-loader

[Link] 2/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

This will install wepback and the dependencies we need for our webpack
configuration. Open in app

Search is only available in version 5 and above of webpack.


Webpack Module Federation

Host App
We are going to start with our webpack configuration

Create a new [Link] file at the root of host/ :

[Link] 3/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

1 // host/[Link]
2 const HtmlWebpackPlugin = require("html-webpack-plugin");
3
4 [Link] = {
5 entry: "./src/index",
6 mode: "development",
7 devServer: {
8 port: 3000,
9 },
10 module: {
11 rules: [
12 {
13 test: /\.(js|jsx)?$/,
14 exclude: /node_modules/,
15 use: [
16 {
17 loader: "babel-loader",
18 options: {
19 presets: ["@babel/preset-env", "@babel/preset-react"],
20 },
21 },
22 ],
23 },
24 ],
25 },
26 plugins: [
27 new HtmlWebpackPlugin({
28 template: "./public/[Link]",
29 }),
30 ],
31 resolve: {
32 extensions: [".js", ".jsx"],
33 },
34 target: "web",
35 };

[Link] hosted with ❤ by GitHub view raw

This is a basic webpack example to get our js and jsx code transpiled using babel-

loader and injected into an html template.

Update [Link] scripts


Next, we need a new start script that utilizes our webpack config:

[Link] 4/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

1 "scripts":{
2 "start": "webpack serve"
3 }

[Link] hosted with ❤ by GitHub view raw

Now we can get to the meat of the host app.

[Link]
First, we need the [Link] entry to our app. We are importing another file
[Link] that renders the React app.

We need this extra layer of indirection because it gives Webpack a chance to load all
of the imports it needs to render the remote app.

Otherwise, you would see an error along the lines of:

Shared module is not available for eager consumption

1 // host/src/[Link]
2 import("./bootstrap");
3
4 // Note: It is important to import bootstrap dynamically using import() otherwise you wi

[Link] hosted with ❤ by GitHub view raw

[Link]
Next, we define the [Link] file that renders our React application.

1 // host/src/[Link]
2 import React from "react";
3 import ReactDOM from "react-dom/client";
4 import App from "./App";
5
6 const root = [Link]([Link]("root"));
7 [Link](
8 <[Link]>
9 <App />
10 </[Link]>
11 );

[Link] hosted with ❤ by GitHub view raw

[Link] 5/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

[Link]
Now we are ready to write our [Link] file where the app’s main logic happens. Here
we will load two components from remote which we will define later.

import("Remote/App") will dynamically fetch the Remote app’s [Link] React


component.

We need to use a lazy loader and an ErrorBoundary component to create a smooth


experience for users in case the fetching takes a long time or introduces errors in
our host app.

[Link] 6/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

1 // host/src/[Link]
2 import React from "react";
3 import ErrorBoundary from "./ErrorBoundary";
4 const RemoteApp = [Link](() => import("Remote/App"));
5 const RemoteButton = [Link](() => import("Remote/Button"));
6
7 const RemoteWrapper = ({ children }) => (
8 <div
9 style={{
10 border: "1px solid red",
11 background: "white",
12 }}
13 >
14 <ErrorBoundary>{children}</ErrorBoundary>
15 </div>
16 );
17
18 export const App = () => (
19 <div style={{ background: "rgba(43, 192, 219, 0.3)" }}>
20 <h1>This is the Host!</h1>
21 <h2>Remote App:</h2>
22 <RemoteWrapper>
23 <RemoteApp />
24 </RemoteWrapper>
25 <h2>Remote Button:</h2>
26 <RemoteWrapper>
27 <RemoteButton />
28 </RemoteWrapper>
29 <br />
30 <a href="[Link] to Remote App</a>
31 </div>
32 );
33 export default App;

[Link] hosted with ❤ by GitHub view raw

Add Module Federation


We’re not ready to run the app just yet. Next, we need to add Module Federation to
tell our host where to get the Remote/App and Remote/Button components.

In our [Link] we introduce the ModuleFederationPlugin :

[Link] 7/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

1 // host/[Link]
2 const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
3 const { dependencies } = require("./[Link]");
4
5 [Link] = {
6 //...
7 plugins: [
8 new ModuleFederationPlugin({
9 name: "Host",
10 remotes: {
11 Remote: `Remote@[Link]
12 },
13 shared: {
14 ...dependencies,
15 react: {
16 singleton: true,
17 requiredVersion: dependencies["react"],
18 },
19 "react-dom": {
20 singleton: true,
21 requiredVersion: dependencies["react-dom"],
22 },
23 },
24 }),
25 //...
26 ],
27 //...
28 };

[Link] hosted with ❤ by GitHub view raw

Important things to note:

name is used to distinguish the modules. It is not as important here because we


are not exposing anything, but it is vital in the Remote app.

remotes is where we define the federated modules we want to consume in this


app. You’ll notice we specify Remote as the internal name so we can load the
components using import("Remote/<component>") . But we also define the location
where the remote’s module definition is hosted:
Remote@[Link] . This URL tells us three important
things. The module’s name is Remote , it is hosted on localhost:4000 , and its
module definition is [Link] .

[Link] 8/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

shared is how we share dependencies between modules. This is very important


for React because it has a global state, meaning you should only ever run one
instance of React and ReactDOM in any given app. To achieve this in our
architecture, we are telling webpack to treat React and ReactDOM as singletons,
so the first version loaded from any modules is used for the entire app. As long
as it satisfies the requiredVersion we define. We are also importing all of our
other dependencies from [Link] and including them here, so we
minimize the number of duplicate dependencies between our modules.

Now, if we run npm start in the host app we should see something like:

This means our host app is configured, but our remote app is not exposing anything
yet. So we need to configure that next.

Remote App
Let’s start with the webpack config. Since we now have some knowledge of Module
Federation, let’s use it from the get-go:

[Link] 9/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

1 // remote/[Link]
2 const HtmlWebpackPlugin = require("html-webpack-plugin");
3 const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
4 const path = require("path");
5 const { dependencies } = require("./[Link]");
6
7 [Link] = {
8 entry: "./src/index",
9 mode: "development",
10 devServer: {
11 static: {
12 directory: [Link](__dirname, "public"),
13 },
14 port: 4000,
15 },
16 module: {
17 rules: [
18 {
19 test: /\.(js|jsx)?$/,
20 exclude: /node_modules/,
21 use: [
22 {
23 loader: "babel-loader",
24 options: {
25 presets: ["@babel/preset-env", "@babel/preset-react"],
26 },
27 },
28 ],
29 },
30 ],
31 },
32 plugins: [
33 new ModuleFederationPlugin({
34 name: "Remote",
35 filename: "[Link]",
36 exposes: {
37 "./App": "./src/App",
38 "./Button": "./src/Button",
39 },
40 shared: {
41 ...dependencies,
42 react: {
43 singleton: true,
44 requiredVersion: dependencies["react"],
45 },
46 "react-dom": {
47 singleton: true,
48 requiredVersion: dependencies["react-dom"],
[Link] 10/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming
48 requiredVersion: dependencies[ react dom ],
49 },
50 },
51 }),
52 new HtmlWebpackPlugin({
53 template: "./public/[Link]",
54 }),
55 ],
56 resolve: {
57 extensions: [".js", ".jsx"],
58 },
59 target: "web",
60 };

remote webpack config js hosted with ❤ by GitHub view raw


The important things to note are:

Our webpack dev server runs at localhost:4000

The remote module’s name is Remote

The filename is [Link]

Combining these will allow our host to find the remote code at
Remote@[Link]

exposes is where we define the code we want to share in the [Link] file.
Here we are exposing two: <App /> and <Button /> .

Now let’s set up those components and our Remote app so it can run independently.

[Link]
Similar to the host app, we need a dynamic import in our webpack entry.

1 // /remote/src/[Link]
2 import("./bootstrap");

[Link] hosted with ❤ by GitHub view raw

[Link]

[Link] 11/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

1 // remote/src/[Link]
2 import React from "react";
3 import ReactDOM from "react-dom/client";
4 import App from "./App";
5
6 const root = [Link]([Link]("root"));
7 [Link](
8 <[Link]>
9 <App />
10 </[Link]>
11 );

[Link] hosted with ❤ by GitHub view raw

[Link]
The Remote app is much simpler than the Host:

1 // remote/src/[Link]
2 import React from "react";
3
4 export const App = () => {
5 return <div>Hello from the other side</div>;
6 };
7 export default App;

[Link] hosted with ❤ by GitHub view raw

[Link]
And we also want to expose a <Button /> component

1 // remote/src/[Link]
2 import React from "react";
3
4 export const Button = () => <button>Hello!</button>;
5
6 export default Button;

[Link] hosted with ❤ by GitHub view raw

Now the Remote app is fully configured, and if you run npm start you should see a
blank page with “Hello from the other side.”

Putting it all together

[Link] 12/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

Now if we run npm start in both the host/ and remote/ directories, we should see
the Host app running on localhost:3000 and the remote app running on
localhost:4000 .

The host app would look something like this:

Congratulations! You’ve now configured a Micro Frontend app using React.

Development
You can simplify the development flow by configuring yarn workspaces at the root
level: [Link]

Deployment
We only covered running the Micro Frontend locally. If you want to deploy them,
you would deploy each app separately to their CDN or hosting service and configure
the webpack definitions to use environment variables or some other way to update
the URLs in the ModuleFederationPlugin definitions.

You can find an example of this in my more advanced example app:


[Link]

If you enjoyed this article, please follow me on Medium for more stories about
micro frontends and Webpack Module Federation.

Resources
[Link] 13/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

Code for this example:

GitHub - rautio/react-micro-frontend-example: Simple example


of using React in a micro-frontend…
Example of using React in host-remote micro-frontend pattern with
Webpack Module Federation Run the following commands…
[Link]

A more advanced example:

GitHub - rautio/micro-frontend-demo: Demo repo for


showcasing a micro frontend architecture
A sample repo for demoing a micro frontend architecture setup.
Main Host App: [Link] Products Remote…
[Link]

React Micro Frontends Webpack JavaScript Programming

Follow

Written by Oskari Rautiainen


476 Followers · Writer for Better Programming

UI Architect focused on web development and data problems. Building products and sharing as I learn in the
process. [Link]

More from Oskari Rautiainen and Better Programming

[Link] 14/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

Oskari Rautiainen in Better Programming

Zustand in a Micro Frontend


State management made simple

Jun 3, 2022 183 1

[Link] 15/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

Benoit Ruiz in Better Programming

Advice From a Software Engineer With 8 Years of Experience


Practical tips for those who want to advance in their careers

Mar 20, 2023 17.3K 304

Emily Dresner in Better Programming

Why an Engineering Manager Should Not Review Code


When discussing team organization, I am often asked: “Why don’t you have the tech lead
manage the team?” My response is to hiss like a…

[Link] 16/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

May 11, 2023 4.5K 50

Oskari Rautiainen in Better Programming

4 Ways to Use Dynamic Remotes in Module Federation


How you can configure URLs for your federated remote modules dynamically.

Jul 11, 2022 219

See all from Oskari Rautiainen

See all from Better Programming

Recommended from Medium

[Link] 17/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

François Roget

How to build a dynamic micro-frontend architecture in React?


First of all, what is this Micro-frontend thing?

Feb 24

Lester Sconyers

Dynamic Module Federation with Vite


There are several scenarios where dynamic module federation would be helpful like A/B
Testing. Let’s build a React app that does just that.

[Link] 18/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

May 14 56 2

Lists

General Coding Knowledge


20 stories · 1436 saves

Stories to Help You Grow as a Software Developer


19 stories · 1238 saves

Coding & Development


11 stories · 718 saves

ChatGPT
21 stories · 738 saves

Nitsan Cohen in Bits and Pieces

How To Share States Between React Micro-Frontends using Module-


Federation?
Share states between React Micro-Frontends using Module-Federation and Bit!

Dec 1, 2023 875 6

[Link] 19/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

Anahit Vardevanyan in Octa Labs Insights

Reduce Ant Design Bundle Size Multiple Times


Large bundle sizes can lead to slower page load times and decreased performance, impacting
user experience. To fix this problem, we suggest…

Mar 27 28

Ekinzdaviz

Implementing Micro Frontends in React


Introduction

[Link] 20/21
01/08/2024, 09:46 How to Use Webpack Module Federation in React | by Oskari Rautiainen | Better Programming

Mar 29

Akhshy Ganesh

Create a React, MFE webpack Module Federation


Hi, welcome to this DIY project,

Jun 14

See more recommendations

[Link] 21/21

Common questions

Powered by AI

The key components of a Host-Remote Micro Frontend architecture using React and Webpack Module Federation include the Host application and the Remote applications. The Host application acts as the main entry point, which imports and renders components from Remote applications. This is achieved through dynamic imports using Webpack's ModuleFederationPlugin, which requires configuration such as defining remotes and shared modules. The Host app loads remote components lazily using React.lazy and uses an ErrorBoundary for error handling. The Remote applications expose modules that the Host application consumes, each having its Webpack configuration specifying the exposed components and shared singleton React dependencies to maintain consistency across the application .

Using an ErrorBoundary component when fetching remote components in React applications configured with Module Federation is necessary because it provides a graceful error handling mechanism for handling fetch failures or runtime errors during component loading. As remote components are loaded asynchronously, network issues or component errors can disrupt the user experience by halting render cycles. An ErrorBoundary allows the application to catch errors and display fallback UI, maintaining user engagement and application stability without crashing. This ensures smoother user interactions, especially in situations where remote components might be temporarily unavailable or incorrect .

Potential issues in a Micro Frontend architecture include increased complexity in managing multiple applications, risk of dependency conflicts, challenges with state management, and potential performance overhead due to loading multiple components. These can be mitigated by carefully configuring Webpack Module Federation, such as ensuring React and ReactDOM are treated as singletons to avoid duplication and conflicts. State management can be handled using global state libraries like Zustand or through context APIs. To manage complexity, clear interfaces and contracts between micro frontends should be established, with comprehensive testing to ensure compatibility. Performance can be optimized through effective code splitting, caching strategies, and minimizing shared dependencies by tightly specifying required versions .

Using a lazy loader in the context of Micro Frontends implemented with React provides several benefits, including improved load times and resource efficiency. Lazy loading defers loading of components until they are needed, which reduces the initial loading time of the application. This can lead to faster startup and improved performance metrics by decreasing the payload size. It also optimizes memory usage, as only necessary components are loaded dynamically based on user interaction or navigation. Additionally, lazy loading contributes to better user experience by allowing seamless integration of dynamic content with reduced latency .

To configure a remote app to expose components in a micro frontend setup, the webpack.config.js of the remote app must be modified to include the ModuleFederationPlugin. Within this configuration, the 'name' attribute should identify the remote app, and the 'exposes' attribute should list the modules or components to be shared, with the corresponding file paths. The 'filename' attribute defines the entry file that handles requests for these components, commonly set to 'moduleEntry.js'. Lastly, shared dependencies must be declared, specifying them as singletons if needed, to coordinate versions with the host app .

Webpack's ModuleFederationPlugin facilitates the sharing of code between a host and remote applications by allowing JavaScript applications to share code dynamically at runtime. It defines configurations for remotes—specifying external applications that can be consumed, and exposes—specifying parts of an application that it shares with others. The plugin also manages shared dependencies, ensuring that singletons like React and ReactDOM are used globally to prevent duplication, thus maintaining application consistency. The 'shared' option in the configuration handles shared dependencies, specifying which modules should be treated as singletons with their required versions, reducing redundancy and ensuring compatibility .

Dynamic imports play a crucial role in loading remote components in a React micro frontend using Webpack Module Federation. They allow the host application to import a remote component only when needed, which optimizes loading time and reduces unused resource overhead. This is done using the import() function, which Webpack uses to fetch the remote app’s components on-demand. This method facilitates code splitting and lazy-loading of components, contributing to smoother initial loading and efficient resource utilization. It also helps manage dependencies more effectively by loading them when required and mitigating potential conflicts with shared modules .

Treating React as a singleton in a Micro Frontend setup is important because React maintains a global application state. Running multiple instances of React can lead to inconsistencies and unexpected behavior due to duplicated state and lifecycle management across different parts of the application. By defining React as a singleton in the Webpack configuration, it ensures that only one version of React is loaded and used across all federated modules, maintaining a consistent state management and reducing the memory footprint. This configuration is critical to prevent potential conflicts or performance issues in a distributed application environment .

Deploying micro frontend applications differs from traditional monolithic applications as each micro frontend is an independently deployable unit. This architecture allows agile and iterative deployments where only the modified parts need to be redeployed, reducing downtime and risk of regression impacting the entire application. However, it requires careful dependency and API versioning management to ensure compatibility between different modules. Hosting services need to support separate URLs or CDNs for each micro frontend, and environment variables must be managed to direct module federation configurations correctly. Coordinating updates across micro frontends while maintaining system coherence is another challenge unique to micro frontends .

Webpack's ModuleFederationPlugin handles shared dependencies by allowing applications to specify modules that should be treated as singletons across federated modules. It uses the 'shared' configuration to ensure that the first version of a shared dependency loaded is used throughout the entire application. This approach reduces redundancy by avoiding multiple versions of libraries being loaded, which is crucial for libraries like React that should maintain a single application state. Each dependency can also specify a required version, ensuring compatibility and preventing version mismatches across different federated modules .

You might also like