<?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: Bhuvan Sabarathnam</title>
    <description>The latest articles on DEV Community by Bhuvan Sabarathnam (@sbhuvane).</description>
    <link>https://dev.to/sbhuvane</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%2F621539%2F3d702877-5272-456a-8397-a4f0ae96711a.png</url>
      <title>DEV Community: Bhuvan Sabarathnam</title>
      <link>https://dev.to/sbhuvane</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sbhuvane"/>
    <language>en</language>
    <item>
      <title>Micro Frontend in Angular: Using Module Federation</title>
      <dc:creator>Bhuvan Sabarathnam</dc:creator>
      <pubDate>Mon, 03 May 2021 17:41:12 +0000</pubDate>
      <link>https://dev.to/sbhuvane/micro-frontend-in-angular-using-module-federation-31om</link>
      <guid>https://dev.to/sbhuvane/micro-frontend-in-angular-using-module-federation-31om</guid>
      <description>&lt;p&gt;In this post, we will implement Micro-Frontends in Angular using Webpack 5 Module Federation.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Credit: This post is based on this &lt;a href="https://www.angulararchitects.io/aktuelles/the-microfrontend-revolution-part-2-module-federation-with-angular/" rel="noopener noreferrer"&gt;article&lt;/a&gt; written by Manfred Steyer&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;May-12-2021 Update:&lt;/strong&gt; Added Dockerfiles for both the projects. Please check the Running the applications section.&lt;/p&gt;

&lt;h2&gt;
  
  
  Table Of Contents
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Pre-Requisites&lt;/li&gt;
&lt;li&gt;Create Host Application&lt;/li&gt;
&lt;li&gt;Create Microfrontend Application with feature module&lt;/li&gt;
&lt;li&gt;Add Module Federation&lt;/li&gt;
&lt;li&gt;Webpack Config changes&lt;/li&gt;
&lt;li&gt;Route changes in Host&lt;/li&gt;
&lt;li&gt;Running the applications&lt;/li&gt;
&lt;li&gt;Conclusion&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Pre-Requisites: &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Angular CLI: 11.2.8&lt;/li&gt;
&lt;li&gt;Node: 15.4.0&lt;/li&gt;
&lt;li&gt;Yarn: 1.22.10&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We will be using yarn as package manager instead of NPM. Why? We will be using Webpack 5 Module Federation with Angular 11. Angular CLI 11 uses webpack version 4. We will be overriding the webpack version in package.json and yarn is required to override the web pack version for angular cli.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Host Application &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Set Yarn as package manager&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ng config cli.packageManager yarn 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Any &lt;code&gt;ng add&lt;/code&gt; or &lt;code&gt;ng update&lt;/code&gt; command will yarn instead of rpm to install the packages.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Create a workspace&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ng new angular-mfe-example --createApplication="false" 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above command will create a workspace with no projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Create host (Shell) app&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ng g applicatie host --routing --style=css 


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; Create home component&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ng g c home --project=host


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 5:&lt;/strong&gt; Update Route to add path to Home and change AppComponent&lt;/p&gt;

&lt;p&gt;Add Route to app-routing.module.ts&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%2Fc3lkj17ui1e1l07lrizv.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%2Fc3lkj17ui1e1l07lrizv.png" alt="app-routing.module.ts changes to add route to Home"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Clean up app.component.html&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%2Fzzgj2khbcms455s1m1m8.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%2Fzzgj2khbcms455s1m1m8.png" alt="Cleaned up app.component.html"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6:&lt;/strong&gt; Run the application&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ng serve host


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Run the host app. It should run in default port 4200&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%2Fob8l288dgvrfkia645tl.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%2Fob8l288dgvrfkia645tl.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Create Microfrontend Application with feature module &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;We will now create another application under the same workspace. The steps to create it are the same as above.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Create mfe1 application and home component&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ng g application mfe1 --routing --style=css

ng g c home --project=mfe1



&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;mfe1 project will get created under the main workspace&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Create a new feature module under mfe1&lt;/p&gt;

&lt;p&gt;Create a new feature module mfefeature and a component under the feature module&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ng g m mfefeature --routing --project=mfe1

ng g c mfefeature --project=mfe1


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Add the route to the mfefeature component in the mfefeature-routing.module.ts&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%2Fsnyoicye2e5qkvmx0o9z.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%2Fsnyoicye2e5qkvmx0o9z.png" alt="mfefeature component route"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Change App routing&lt;br&gt;
Update routing module to add path to home component under mfe1.&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%2Fxtudtweooa8gfx2tzzub.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%2Fxtudtweooa8gfx2tzzub.png" alt="Update routing module to add path to home component under mfe1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Update routing module to add path to mfe1. The mfefeature module is lazy loaded&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

{
    path: 'mfe1',
    loadChildren: () =&amp;gt; 
      import("./mfefeature/mfefeature.module").then((m) =&amp;gt; m.MfefeatureModule),
  },


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2F8jq1fvf2h3zm1tszou2y.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%2F8jq1fvf2h3zm1tszou2y.png" alt="Path to mfe1"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please ensure that home component is pointing to the one under mfe1 project and not host.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; Change HomeComponent&lt;/p&gt;

&lt;p&gt;Change home.component.html&lt;br&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%2Fkf37dyunnigsfuqa41i0.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%2Fkf37dyunnigsfuqa41i0.png" alt="Add home in MFE1 works in home.component.html"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 5:&lt;/strong&gt; Change AppComponent in mfe1&lt;/p&gt;

&lt;p&gt;Change app.component.html to include links to home and mfe1&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%2Fs8mlmuh4nsnt1e1932fy.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%2Fs8mlmuh4nsnt1e1932fy.png" alt="App Component changes"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6:&lt;/strong&gt; Run the application&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ng serve mfe1


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Fbe4ig5tkofi7v9fyxg4k.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%2Fbe4ig5tkofi7v9fyxg4k.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Run the mfe1 app. It should run in default port 4200.&lt;/p&gt;

&lt;p&gt;At the end of this step, we have created 2 applications in the same workspace. The mfe1 application has a feature module. This feature module will be loaded as Microfrontend in the host application in the subsequent sections.&lt;/p&gt;

&lt;h3&gt;
  
  
  Add Module Federation &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Angular CLI does not expose the webpack to us. We need to install custom builder to enable module federation.&lt;/p&gt;

&lt;p&gt;Add &lt;a href="https://www.npmjs.com/package/@angular-architects/module-federation" rel="noopener noreferrer"&gt;@angular-architects/module-federation&lt;/a&gt; package to both the projects.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ng add @angular-architects/module-federation --project host --port 4200

ng add @angular-architects/module-federation --project mfe1 --port 5000


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The above command creates web pack config files and updates angular.json.&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%2F1sany7tckdmsrt4ujsdp.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%2F1sany7tckdmsrt4ujsdp.png" alt="Changes due to module-federation"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Webpack Config changes &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Add Webpack5 to the workspace&lt;/p&gt;

&lt;p&gt;We will now add webpack5 to the workspace. Add the below entry to package.json&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

"resolutions": {
    "webpack": "^5.4.0",
    "license-webpack-plugin": "2.3.17"
  },


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&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%2Frk339ebjwkf7rnbdjxef.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%2Frk339ebjwkf7rnbdjxef.png" alt="webpack addition"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;We need to add &lt;a href="mailto:license-webpack-plugin@2.3.17"&gt;license-webpack-plugin@2.3.17&lt;/a&gt; as Angular11 uses 2.3.11 version which gives an error when used with webpack5.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Add Modulefederated plugin to mfe1&lt;/p&gt;

&lt;p&gt;Locate webpack.config.js under mfe1 project and uncomment the config values under &lt;code&gt;// For remotes (please adjust)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Make the following changes&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

name: "mfe1",
filename: "mfe1remoteEntry.js",
exposes: {
    './MfefeatureModule': './projects/mfe1/src/app/mfefeature/mfefeature.module.ts',
        },  


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We are exposing mfefeature.module under the name MfefeatureModule. This name will be used when we are lazy loading this module in host's app-routing.module.ts&lt;br&gt;
The feature module will be available in mfe1remoteEntry.js&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Add Modulefederated plugin to host&lt;/p&gt;

&lt;p&gt;Locate webpack.config.js under host project and uncomment the lines under &lt;code&gt;// For hosts (please adjust)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Make the following changes&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

remotes: {
     "mfe1": "mfe1@http://localhost:5000/mfe1remoteEntry.js",
},


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;We are mapping the name 'mfe1' to the path where the remote can be found. Please note that the mfe1 project needs to run in port 5000 and we are pointing to mfe1remoteentry.js which is the name we gave in the mfe1's webpack.config.js&lt;/p&gt;

&lt;h3&gt;
  
  
  Route changes in Host &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Step 1:&lt;/strong&gt; Add route to mfe1 feature module &lt;/p&gt;

&lt;p&gt;Add path to mfe1 and lazy load the mfe feature module&lt;/p&gt;

&lt;p&gt;In host's app-routing.module.ts &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

{
    path: 'mfe1',
    loadChildren: () =&amp;gt;
      import('mfe1/MfefeatureModule').then((m) =&amp;gt; {
        return m.MfefeatureModule;
      }),
  }


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Note that in the import statement we are using MfeFeatureModule, which is the name of the module we gave in mfe1's webpack.config.js&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 2:&lt;/strong&gt; Declare MfeFeatureModule&lt;/p&gt;

&lt;p&gt;The path &lt;code&gt;mfe1/MfeFeatureModule&lt;/code&gt; mentioned in the import statement does not "exist" within host project. When we compile the host project it will throw an error.&lt;/p&gt;

&lt;p&gt;To fix the error, we will create decl.d.ts under host and declare the module&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

declare module 'mfe1/MfefeatureModule'


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Add route for mfe in Appcomponent&lt;/p&gt;

&lt;p&gt;In app.component.html, make the following changes&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

&amp;lt;h1&amp;gt;Angular MFE Host&amp;lt;/h1&amp;gt;
&amp;lt;a routerLink='/'&amp;gt;Main&amp;lt;/a&amp;gt; &amp;amp;#160;
&amp;lt;a routerLink='/mfe1'&amp;gt;Link to MFE&amp;lt;/a&amp;gt;
&amp;lt;router-outlet&amp;gt;&amp;lt;/router-outlet&amp;gt;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;h3&gt;
  
  
  Running the applications &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Option 1:&lt;/strong&gt; Run in terminal&lt;/p&gt;

&lt;p&gt;Open 2 command terminals&lt;/p&gt;

&lt;p&gt;In terminal 1 run&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ng serve host


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;In terminal 2 run&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

ng serve mfe1


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;Open localhost:4200 &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%2Fzu3q77lbdydrzx695ytn.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%2Fzu3q77lbdydrzx695ytn.png" alt="Host Landing page"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;you will able to navigate to the mfe1 which is actually running in localhost:5000&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%2F5j3rsxo5gvkeqjmp9kt8.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%2F5j3rsxo5gvkeqjmp9kt8.png" alt="mfe1 in host"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Option 2:&lt;/strong&gt; Dockerize the apps and run in containers&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Step 1: *&lt;/em&gt; Create nginx default configuration file&lt;/p&gt;

&lt;p&gt;Under the main folder create a folder nginx.&lt;/p&gt;

&lt;p&gt;Inside this folder create a file "default.conf" and copy the below commands&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

server {

  listen 80;

  sendfile on;

  default_type application/octet-stream;


  gzip on;
  gzip_http_version 1.1;
  gzip_disable      "MSIE [1-6]\.";
  gzip_min_length   1100;
  gzip_vary         on;
  gzip_proxied      expired no-cache no-store private auth;
  gzip_types        text/plain text/css application/json application/javascript application/x-javascript text/xml application/xml application/xml+rss text/javascript;
  gzip_comp_level   9;


  root /usr/share/nginx/html;


  location / {
    try_files $uri $uri/ /index.html =404;
  }

}


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;This configuration is copied during the creation of the docker image.&lt;/p&gt;

&lt;p&gt;*&lt;em&gt;Step 2: *&lt;/em&gt; Create Dockerfile for host&lt;br&gt;
In the main folder create HostDockerfile. This is in the same level as projects folder.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

FROM node:15-alpine as builder

COPY package.json  ./

RUN yarn install 

RUN mkdir /ng-app

RUN mv ./node_modules ./ng-app

WORKDIR /ng-app

COPY . .

RUN npm run ng build --prod --project=host

FROM nginx
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /ng-app/dist/host /usr/share/nginx/html

CMD ["nginx", "-g", "daemon off;"]


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 3:&lt;/strong&gt; Create Docker image for host using the below command&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

docker build -t host -f .\HostDockerfile


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The name of the docker image is host. Please note that the name of the dockerfile is "HostDockerfile". &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 4:&lt;/strong&gt; Create Dockerfile for mfe1&lt;br&gt;
In the main folder create MfeDockerfile. This is in the same level as projects folder.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

FROM node:15-alpine as builder

COPY package.json  ./

RUN yarn install 

RUN mkdir /mfe-app

RUN mv ./node_modules ./mfe-app

WORKDIR /mfe-app

COPY . .

RUN npm run ng build --prod --project=mfe1

FROM nginx
COPY nginx/default.conf /etc/nginx/conf.d/default.conf
COPY --from=builder /mfe-app/dist/mfe1 /usr/share/nginx/html

CMD ["nginx", "-g", "daemon off;"]


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Step 5:&lt;/strong&gt; Create Docker image for mfe1 using the below command&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

docker build -t mfe1 -f .\MfeDockerfile


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The name of the docker image is mfe1. Please note that the name of the dockerfile is "MfeDockerfile". &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Step 6:&lt;/strong&gt; Create containers for host and mfe1&lt;/p&gt;

&lt;p&gt;Run the below commands to create and run the containers&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

docker run -d -p 4200:80 host

docker run -d -p 5000:80 mfe1


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The host expects mfe1 to run in port 5000, hence running the mfe1 container in port 5000.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion &lt;a&gt;&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;This is a simple tutorial that demonstrates implementation of Microfrontend using Webpack Module Federation. &lt;/p&gt;

&lt;p&gt;You can refer to my &lt;a href="https://github.com/sbhuvane/Angular-Microfrontend-Demo" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt; for the completed solution.&lt;/p&gt;

</description>
      <category>angular</category>
      <category>microfrontend</category>
      <category>tutorial</category>
      <category>docker</category>
    </item>
  </channel>
</rss>
