<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sam Ho</title>
    <description>The latest articles on DEV Community by Sam Ho (@samhoooo).</description>
    <link>https://dev.to/samhoooo</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1966062%2F4b4f204c-20fa-4bf1-8d62-ed540b52de3c.jpeg</url>
      <title>DEV Community: Sam Ho</title>
      <link>https://dev.to/samhoooo</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/samhoooo"/>
    <language>en</language>
    <item>
      <title>Micro Frontend with Module Federation in React</title>
      <dc:creator>Sam Ho</dc:creator>
      <pubDate>Wed, 16 Oct 2024 20:17:36 +0000</pubDate>
      <link>https://dev.to/samhoooo/micro-frontend-with-module-federation-in-react-3g4m</link>
      <guid>https://dev.to/samhoooo/micro-frontend-with-module-federation-in-react-3g4m</guid>
      <description>&lt;p&gt;This article is originally published on &lt;a href="https://medium.com/@samhodev/microfrontend-with-module-federation-in-react-98b72b347238" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This article will give you an overview of using micro frontend architecture and module federation to build scalable and efficient web applications, with a step-by-step guide to building a micro frontend using module federation in React.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Micro frontend?
&lt;/h2&gt;

&lt;p&gt;Micro frontend is an architectural pattern for building web applications that involves breaking down a large frontend monolith into smaller, more manageable pieces. Each piece is an independent application, or microfrontend, that can be developed, tested, and deployed separately. This allows teams to work more efficiently and independently, as well as improve the performance and scalability of the overall application.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Module Federation?
&lt;/h2&gt;

&lt;p&gt;Module Federation is a way to share code between different applications or micro-frontends. It allows you to distribute your code across multiple domains, which is essential when working with large-scale applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  How Does it Work?
&lt;/h2&gt;

&lt;p&gt;Module Federation is a system that allows you to use parts of an application in another application without having to import the entire application. This means that you can break down your application into smaller modules, making it easier to manage and update.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9mldrdhltji39pa90sc.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fc9mldrdhltji39pa90sc.png" alt="Image description" width="800" height="576"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With module federation, you can share code between multiple applications.&lt;/p&gt;

&lt;h2&gt;
  
  
  Benefits of Module Federation
&lt;/h2&gt;

&lt;p&gt;Module Federation has several benefits, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Scalability&lt;/strong&gt;: With Module Federation, you can easily add new features to your application without having to rewrite your entire application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Efficiency&lt;/strong&gt;: By breaking down your application into smaller modules, you can make your application more efficient, reducing the time it takes to load and run.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Collaboration&lt;/strong&gt;: Module Federation allows developers to work together more easily, as it makes it easier to share code between applications.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Example
&lt;/h2&gt;

&lt;p&gt;Here is a demo to build a micro frontend using Module Federation. We are going to build two applications: Home App and Header App.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/samhoooo/module-federation-demo?source=post_page-----98b72b347238--------------------------------" rel="noopener noreferrer"&gt;Full source code&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxxtqfp04k3nztwl3q88n.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxxtqfp04k3nztwl3q88n.png" alt="Image description" width="800" height="538"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You can follow these steps:&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1 — Create Applications
&lt;/h2&gt;

&lt;p&gt;Create a new React application using create-react-app or your preferred method. In your root directory, create two applications:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-react-app home-app

npx create-react-app header-app
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2 — Install Webpack 5
&lt;/h2&gt;

&lt;p&gt;Within each application, install webpack 5 and related dependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#NPM
npm install -–save-dev webpack webpack-cli html-webpack-plugin webpack-dev-server babel-loader css-loader

#Yarn
yarn add -D webpack webpack-cli html-webpack-plugin webpack-dev-server babel-loader css-loader
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 3 — Customize Home Page
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzgxqmtzytbilr2nynyog.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzgxqmtzytbilr2nynyog.png" alt="Image description" width="800" height="514"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Customize your Home Page. For example, In home-app/App.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'; // Must be imported for webpack to work
import './App.css';

function App() {
  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;div className="container"&amp;gt;This is my home page&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run your home-app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ./home-app &amp;amp;&amp;amp; yarn &amp;amp;&amp;amp; yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 4— Customize Header Page
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv089sexd2f74hy5hz6qi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fv089sexd2f74hy5hz6qi.png" alt="Image description" width="800" height="496"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Customize your Header Page. For example, In header-app/App.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react'; // Must be imported for webpack to work
import './App.css';

function App() {
  return (
    &amp;lt;div className="HeaderApp"&amp;gt;
      &amp;lt;div&amp;gt;Header&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run your header-app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ./home-app &amp;amp;&amp;amp; yarn &amp;amp;&amp;amp; yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5— Webpack Configuration
&lt;/h2&gt;

&lt;p&gt;Create webpack.config.js file at the root of header-app/ and home-app/:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;//home-app/webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
    entry: "./src/index",
    mode: "development",
    devServer: {
        port: 3000,  // port 3001 for header-app
    },
    module: {
        rules: [
            {
                test: /\.(js|jsx)?$/,
                exclude: /node_modules/,
                use: [
                    {
                    loader: "babel-loader",
                    options: {
                        presets: ["@babel/preset-env", "@babel/preset-react"],
                    },
                    },
                ],
            },
            {
                test: /\.css$/i,
                use: ["style-loader", "css-loader"],
            },
        ],
    },
    plugins: [
        new HtmlWebpackPlugin({
            template: "./public/index.html",
        }),
    ],
    resolve: {
        extensions: [".js", ".jsx"],
    },
    target: "web",
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify header-app/src/index.js &amp;amp; home-app/src/index.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('app'));
root.render(
  &amp;lt;React.StrictMode&amp;gt;
    &amp;lt;App /&amp;gt;
  &amp;lt;/React.StrictMode&amp;gt;
);
Modify header-app/public/index.html &amp;amp; home-app/public/index.html:

&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html lang="en"&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="UTF-8" /&amp;gt;
    &amp;lt;meta http-equiv="X-UA-Compatible" content="IE=edge" /&amp;gt;
    &amp;lt;meta name="viewport" content="width=device-width, initial-scale=1.0" /&amp;gt;
    &amp;lt;title&amp;gt;React with Webpack&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;div id="app"&amp;gt;&amp;lt;/div&amp;gt;

    &amp;lt;script src="main.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Change the start script in header-app/package.json &amp;amp; home-app/package.json to utilize our webpack config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"scripts": {
    "start": "webpack serve",
    "build": "webpack --mode production",
 },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run your header-app and home-app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd home-app &amp;amp;&amp;amp; yarn start
cd header-app &amp;amp;&amp;amp; yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 6— Module Federation Configuration
&lt;/h2&gt;

&lt;p&gt;First, we need add a file entry.js as an entry to each of our app.&lt;/p&gt;

&lt;p&gt;We need this additional layer of indirection because it allows Webpack to load all necessary imports for rendering the remote app.&lt;/p&gt;

&lt;p&gt;Create header-app/entry.js and home-app/entry.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import('./index.js')
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify the entry of header-app/webpack.config.js and home-app/webpack.config.js&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
    entry: "./src/entry.js",
    //...
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 7— Exposes Header for Module Federation
&lt;/h2&gt;

&lt;p&gt;Now we need to expose Header for home-app to use, in our header-app/webpack.config.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// header-app/webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
// import ModuleFederationPlugin from webpack
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin"); 
// import dependencies from package.json, which includes react and react-dom
const { dependencies } = require("./package.json");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
    //...
    plugins: [
        //...
        new ModuleFederationPlugin({
            name: "HeaderApp",  // This application named 'HeaderApp'
            filename: "remoteEntry.js",  // output a js file
            exposes: { // which exposes
              "./Header": "./src/App",  // a module 'Header' from './src/App'
            },
            shared: {  // and shared
              ...dependencies,  // some other dependencies
              react: { // react
                singleton: true,
                requiredVersion: dependencies["react"],
              },
              "react-dom": { // react-dom
                singleton: true,
                requiredVersion: dependencies["react-dom"],
              },
            },
        }),
    ],
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start the app, navigate to &lt;a href="http://localhost:3001/remoteEntry.js" rel="noopener noreferrer"&gt;http://localhost:3001/remoteEntry.js&lt;/a&gt;. This is a manifest of all of the modules that are exposed by the header application.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 8— Add Module Federation in Home App
&lt;/h2&gt;

&lt;p&gt;Now we need to add the ModuleFederationPlugin to home-app/webpack.config.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// home-app/webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin");
// import ModuleFederationPlugin from webpack
const ModuleFederationPlugin = require("webpack/lib/container/ModuleFederationPlugin");
// import dependencies from package.json, which includes react and react-dom
const { dependencies } = require("./package.json");

module.exports = {
    //...
    plugins: [
        //...
        new ModuleFederationPlugin({
            name: "HomeApp",  // This application named 'HomeApp'
            // This is where we define the federated modules that we want to consume in this app. 
            // Note that we specify "Header" as the internal name 
            // so that we can load the components using import("Header/"). 
            // We also define the location where the remote's module definition is hosted: 
            // Header@[http://localhost:3001/remoteEntry.js]. 
            // This URL provides three important pieces of information: the module's name is "Header", it is hosted on "localhost:3001", 
            // and its module definition is "remoteEntry.js".
            remotes: { 
                "HeaderApp": "HeaderApp@http://localhost:3001/remoteEntry.js",            
            },
            shared: {  // and shared
                ...dependencies,  // other dependencies
                react: { // react
                    singleton: true,
                    requiredVersion: dependencies["react"],
                },
                "react-dom": { // react-dom
                    singleton: true,
                    requiredVersion: dependencies["react-dom"],
                },
            },
        }),
    ],
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Modify home-app/src/App.js to use the Header component from the remote app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { lazy, Suspense } from 'react'; // Must be imported for webpack to work
import './App.css';

const Header = lazy(() =&amp;gt; import('HeaderApp/Header'));

function App() {
  return (
    &amp;lt;div className="App"&amp;gt;
      &amp;lt;Suspense fallback={&amp;lt;div&amp;gt;Loading Header...&amp;lt;/div&amp;gt;}&amp;gt;
        &amp;lt;Header /&amp;gt;
      &amp;lt;/Suspense&amp;gt;
      &amp;lt;div className="container"&amp;gt;Demo home page&amp;lt;/div&amp;gt;
    &amp;lt;/div&amp;gt;
  );
}

export default App;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run your home-app and header-app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd home-app &amp;amp;&amp;amp; yarn start
cd header-app &amp;amp;&amp;amp; yarn start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Done!
&lt;/h2&gt;

&lt;p&gt;Navigate to Home App &lt;a href="http://localhost:3000" rel="noopener noreferrer"&gt;http://localhost:3000&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And done! You have successfully created a module federated app with a header.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8e8hiomucxgeikimaabb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8e8hiomucxgeikimaabb.png" alt="Image description" width="800" height="522"&gt;&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Micro frontend architecture and module federation are powerful tools for building scalable and efficient web applications. By breaking down a large monolithic frontend into smaller, more manageable pieces, teams can work more efficiently and independently. Module federation then allows developers to share code between applications, enabling collaboration and reducing duplication of effort. By following the steps outlined in this article, you can build your own micro frontend with module federation in React and take advantage of these powerful tools.&lt;/p&gt;




&lt;h2&gt;
  
  
  Useful Resources
&lt;/h2&gt;

&lt;p&gt;The full source code is avaliable in my &lt;a href="https://github.com/samhoooo/module-federation-demo?source=post_page-----98b72b347238--------------------------------" rel="noopener noreferrer"&gt;Github repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have any further questions, feel free to comment below or reach me directly on  &lt;a href="https://www.linkedin.com/in/sam-hoooo/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>react</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>microfrontend</category>
    </item>
  </channel>
</rss>
