{"id":43168,"date":"2022-10-21T16:24:02","date_gmt":"2022-10-21T16:24:02","guid":{"rendered":"https:\/\/polarising.com\/techinside\/?p=43168"},"modified":"2022-10-21T16:24:05","modified_gmt":"2022-10-21T16:24:05","slug":"micro-frontends-basic-example-with-react-tailwind-and-module-federation-2-2","status":"publish","type":"post","link":"https:\/\/polarising.com\/techinside\/micro-frontends-basic-example-with-react-tailwind-and-module-federation-2-2\/","title":{"rendered":"Micro Frontends: Basic example with React, Tailwind and Module Federation. (2\/2)"},"content":{"rendered":"\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>This tutorial is a follow up to my previous Micro Frontend (MFE) article, which tackles the basic &#8220;What, Why, How&#8221; questions of MFEs. The goal is to provide a simple use-case that serves as a launchpad for you to start using Micro Frontends through Module Federation in your projects.<\/p>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Generating the projects.<\/h2>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>In order to display the ease of use of MicroFrontends with Module Federation, I&#8217;m going to provide a basic example using React.<\/p>\n\n\n\n<p>In the directory of your choice, run the command<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\" style=\"text-transform:lowercase\">npx create-mf-app<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>to create a new MFE project. For the purposes of this example, I&#8217;m going to create two projects: host and remote. A few prompts will appear asking for the specs of the project, which for the host are:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"895\" height=\"432\" src=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/command-image-micro-1.jpg\" alt=\"\" class=\"wp-image-43236\" srcset=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/command-image-micro-1.jpg 895w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/command-image-micro-1-300x145.jpg 300w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/command-image-micro-1-768x371.jpg 768w\" sizes=\"auto, (max-width: 895px) 100vw, 895px\" \/><\/figure>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>After choosing the specs, the command will conclude and you can navigate to the new directory and run<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\" style=\"text-transform:lowercase\">npm install <\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>to install all the necessary dependencies. For this example we will need Bootstrap and a router, so you will need to run<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\" style=\"text-transform:lowercase\">npm install react-router-dom<\/p>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\" style=\"text-transform:lowercase\">npm install react-bootstrap bootstrap<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>as well.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Now, going back to the initial directory, we run the same create-mf-app command to generate the remote project, with the following specs:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"895\" height=\"328\" src=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/micro-image-command.jpg\" alt=\"\" class=\"wp-image-43237\" srcset=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/micro-image-command.jpg 895w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/micro-image-command-300x110.jpg 300w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/micro-image-command-768x281.jpg 768w\" sizes=\"auto, (max-width: 895px) 100vw, 895px\" \/><\/figure>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>And then navigating to this project and running<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">npm install<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>In order to run the projects and see the generated pages, run<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">npm start<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>in each of the project&#8217;s directories.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><em><strong>Note:<\/strong> You can choose whichever port numbers you like, just make sure they aren&#8217;t the same for the host and the remote<\/em><\/p>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Creating the Remote Page.<\/h2>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>For the remote page, we could leave it as is since the command creates a boilerplate page with the chosen specs of the project. I prefer to display a more relevant message to the example, so in the remote project navigate to the src directory and create a file called <strong>RemotePage.jsx<\/strong> (src\/RemotePage.jsx) with the following code:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import React from &#8220;react&#8221;;<\/p>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">export default function RemotePage() {<br>&nbsp;&nbsp;&nbsp; return(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;div className=&#8221;mt-10 text-3xl mx-auto max-w-6xl&#8221;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; This is the Remote Page!<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/div&gt;<br>&nbsp;&nbsp;&nbsp; )<br>}<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Now, in <strong>the src\/App.jsx<\/strong> file, change the code to the following:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import React from &#8220;react&#8221;;<br>import ReactDOM from &#8220;react-dom&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import &#8220;.\/index.scss&#8221;;<br>import RemotePage from &#8220;.\/RemotePage&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">&nbsp;const App = () =&gt; (<br>&nbsp; &lt;RemotePage \/&gt;<br>);<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">ReactDOM.render(&lt;App \/&gt;, document.getElementById(&#8220;app&#8221;));<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>After these two steps you should see a page like this:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full is-style-default\"><img loading=\"lazy\" decoding=\"async\" width=\"895\" height=\"594\" src=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/remote-page-image-micro-1.jpg\" alt=\"\" class=\"wp-image-43254\" srcset=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/remote-page-image-micro-1.jpg 895w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/remote-page-image-micro-1-300x199.jpg 300w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/remote-page-image-micro-1-768x510.jpg 768w\" sizes=\"auto, (max-width: 895px) 100vw, 895px\" \/><\/figure>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Configuring the Host.<\/h2>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The host requires a bit more work, so let&#8217;s get to it!<\/p>\n\n\n\n<p>First we need to create a component for the navbar. To do that, navigate to the src directory and create a <strong>NavbarComponent.jsx <\/strong>file:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import React from &#8220;react&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import Container from &#8216;react-bootstrap\/Container&#8217;;<br>import Nav from &#8216;react-bootstrap\/Nav&#8217;;<br>import Navbar from &#8216;react-bootstrap\/Navbar&#8217;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">export default function NavbarComponent() {<br>&nbsp;&nbsp;&nbsp; return (<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Navbar bg=&#8221;light&#8221; expand=&#8221;lg&#8221;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Container&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Navbar.Brand href=&#8221;#home&#8221;&gt;React-Bootstrap&lt;\/Navbar.Brand&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Navbar.Toggle aria-controls=&#8221;basic-navbar-nav&#8221; \/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Navbar.Collapse id=&#8221;basic-navbar-nav&#8221;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Nav className=&#8221;me-auto&#8221;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Nav.Link href=&#8221;\/&#8221;&gt;Home&lt;\/Nav.Link&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Nav&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Navbar.Collapse&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Container&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Navbar&gt;<br>&nbsp;&nbsp;&nbsp; );<br>&nbsp; }<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The navbar will have two tabs, the <strong>Home<\/strong> and the <strong>Remote<\/strong>, which will house our Micro Frontend imported through Module Federation.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><em><strong>Note:<\/strong> You&#8217;ll notice this component uses Bootstrap, so don&#8217;t forget to add it to the <strong>src\/index.html<\/strong> file:<\/em><\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">&lt;!DOCTYPE html&gt;<br>&lt;html lang=&#8221;en&#8221;&gt;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">&lt;head&gt;<br>&nbsp; &lt;meta charset=&#8221;UTF-8&#8243;&gt;<br>&nbsp; &lt;meta name=&#8221;viewport&#8221; content=&#8221;width=device-width, initial-scale=1.0&#8243;&gt;<br>&nbsp; &lt;link<br>&nbsp; rel=&#8221;stylesheet&#8221;<br>&nbsp; href=&#8221;https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@5.2.0-beta1\/dist\/css\/bootstrap.min.css&#8221;<br>&nbsp; integrity=&#8221;sha384-0evHe\/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor&#8221;<br>&nbsp; crossorigin=&#8221;anonymous&#8221;<br>\/&gt;<br>&nbsp; &lt;title&gt;host&lt;\/title&gt;<br>&lt;\/head&gt;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">&lt;body&gt;<br>&nbsp; &lt;div id=&#8221;app&#8221;&gt;&lt;\/div&gt;<br>&lt;\/body&gt;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">&lt;\/html&gt;<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Next, we need to create our Home page and add the router. We&#8217;ll start with the Home page, which will be on the <strong>src\/Home.jsx<\/strong> file:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import React from &#8220;react&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">export default function Home() {<br>&nbsp;&nbsp;&nbsp; return (<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;div className=&#8221;mt-10 text-3xl mx-auto max-w-6xl&#8221;&gt;Home page&lt;\/div&gt;<br>&nbsp;&nbsp;&nbsp; );<br>&nbsp; }<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>And now the router, which will be on the <strong>src\/App.jsx<\/strong> file:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import React from &#8220;react&#8221;;<br>import ReactDOM from &#8220;react-dom&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import &#8220;.\/index.scss&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import { BrowserRouter,&nbsp; Routes, Route} from &#8220;react-router-dom&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import Home from &#8216;.\/Home&#8217;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import NavbarComponent from &#8220;.\/NavbarComponent&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">const App = () =&gt; (<br>&nbsp;&nbsp;&nbsp; &lt;BrowserRouter&gt;<br>&nbsp;&nbsp;&nbsp; &lt;NavbarComponent \/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;div className=&#8221;text-3xl mx-auto max-w-6xl&#8221;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;div className=&#8221;my-10&#8243;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Routes&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Route path=&#8221;\/&#8221; element={ &lt;Home \/&gt;}&gt;&lt;\/Route&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Routes&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/div&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/div&gt;<br>&nbsp;&nbsp;&nbsp; &lt;\/BrowserRouter&gt;<br>&nbsp;&nbsp;&nbsp; );<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">ReactDOM.render(&lt;App \/&gt;, document.getElementById(&#8220;app&#8221;));<\/p>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Exposing the Remote Page.<\/h2>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>After all this setup, it&#8217;s time for some Module Federation Magic. We&#8217;ll start by going to the <strong>\/remote\/webpack.config.js<\/strong> file and exposing our Remote Page:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">plugins: [<br>&nbsp;&nbsp;&nbsp; new ModuleFederationPlugin({<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name: &#8220;remote&#8221;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filename: &#8220;remoteEntry.js&#8221;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; remotes: {},<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exposes: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;.\/RemotePage&#8221;: &#8220;.\/src\/RemotePage.jsx&#8221;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; shared: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;deps,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; react: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton: true,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; requiredVersion: deps.react,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;react-dom&#8221;: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton: true,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; requiredVersion: deps[&#8220;react-dom&#8221;],<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },<br>&nbsp;&nbsp;&nbsp; }),<br>&nbsp;&nbsp;&nbsp; new HtmlWebPackPlugin({<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; template: &#8220;.\/src\/index.html&#8221;,<br>&nbsp;&nbsp;&nbsp; }),<br>&nbsp; ],<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>In the <strong>Plugins<\/strong> array you&#8217;ll see a <strong>ModuleFederationPlugin<\/strong> with a <strong>remotes<\/strong> and <strong>exposes<\/strong> property. Since we want to expose the RemotePage, we&#8217;ll add the path of the component in the <strong>exposes<\/strong>.<\/p>\n\n\n\n<p>The Remote is all done, now on to importing the component in the Host.<\/p>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Importing the Remote.<\/h2>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>In order to import an MFE, we need to go to the <strong>webpack.config.js<\/strong> of the project where we want to import the component and locate the <strong>plugins<\/strong> array, like we did to expose our RemotePage. For our host, it should be in the <strong>host\/webpack.config.js<\/strong> file. To connect both projects, we&#8217;re going to pass to the host the URL of the Remote&#8217;s <strong>remoteEntry.js<\/strong> file:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">plugins: [<br>&nbsp;&nbsp;&nbsp; new ModuleFederationPlugin({<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name: &#8220;host&#8221;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filename: &#8220;remoteEntry.js&#8221;,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; remotes: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; remote: &#8220;remote@http:\/\/localhost:4001\/remoteEntry.js&#8221;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; exposes: {},<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; shared: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8230;deps,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; react: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton: true,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; requiredVersion: deps.react,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;react-dom&#8221;: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; singleton: true,<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; requiredVersion: deps[&#8220;react-dom&#8221;],<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; },<br>&nbsp;&nbsp;&nbsp; }),<br>&nbsp;&nbsp;&nbsp; new HtmlWebPackPlugin({<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; template: &#8220;.\/src\/index.html&#8221;,<br>&nbsp;&nbsp;&nbsp; }),<br>&nbsp; ],<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><em><strong>Note:<\/strong> if you chose another port number for the remote, use that instead of 4001<\/em><\/p>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Using a Micro Frontend.<\/h2>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Now the fun part: using our new component.<\/p>\n\n\n\n<p>First, we&#8217;re going to add a <strong>Remote<\/strong> to our navbar <strong>host\/src\/NavbarComponent.jsx:<\/strong><\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import React from &#8220;react&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import Container from &#8216;react-bootstrap\/Container&#8217;;<br>import Nav from &#8216;react-bootstrap\/Nav&#8217;;<br>import Navbar from &#8216;react-bootstrap\/Navbar&#8217;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">export default function NavbarComponent() {<br>&nbsp;&nbsp;&nbsp; return (<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Navbar bg=&#8221;light&#8221; expand=&#8221;lg&#8221;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Container&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Navbar.Brand href=&#8221;#home&#8221;&gt;React-Bootstrap&lt;\/Navbar.Brand&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Navbar.Toggle aria-controls=&#8221;basic-navbar-nav&#8221; \/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Navbar.Collapse id=&#8221;basic-navbar-nav&#8221;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Nav className=&#8221;me-auto&#8221;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Nav.Link href=&#8221;\/&#8221;&gt;Home&lt;\/Nav.Link&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Nav.Link href=&#8221;\/remote&#8221;&gt;Remote&lt;\/Nav.Link&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Nav&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Navbar.Collapse&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Container&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Navbar&gt;<br>&nbsp;&nbsp;&nbsp; );<br>&nbsp; }<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>And then we&#8217;ll add the Route to our Router in <strong>host\/src\/App.jsx<\/strong> and import the <strong>RemotePage<\/strong> like it was a normal component:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import React from &#8220;react&#8221;;<br>import ReactDOM from &#8220;react-dom&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import &#8220;.\/index.scss&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import { BrowserRouter,&nbsp; Routes, Route} from &#8220;react-router-dom&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import Home from &#8216;.\/Home&#8217;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import NavbarComponent from &#8220;.\/NavbarComponent&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import RemotePage from &#8216;remote\/RemotePage&#8217;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">const App = () =&gt; (<br>&nbsp;&nbsp;&nbsp; &lt;BrowserRouter&gt;<br>&nbsp;&nbsp;&nbsp; &lt;NavbarComponent \/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;div className=&#8221;text-3xl mx-auto max-w-6xl&#8221;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;div className=&#8221;my-10&#8243;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Routes&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Route path=&#8221;\/&#8221; element={ &lt;Home \/&gt;}&gt;&lt;\/Route&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Route path=&#8221;\/remote&#8221; element={&lt;RemotePage \/&gt;}&gt;&lt;\/Route&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Routes&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/div&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/div&gt;<br>&nbsp;&nbsp;&nbsp; &lt;\/BrowserRouter&gt;<br>&nbsp;&nbsp;&nbsp; );<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">ReactDOM.render(&lt;App \/&gt;, document.getElementById(&#8220;app&#8221;));<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Notice how we imported from remote\/RemotePage:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import RemotePage from &#8216;remote\/RemotePage&#8217;<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>We do this because when we specified the remote in the webpack.config.js file, we used<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">remotes: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; remote: &#8220;remote@http:\/\/localhost:4001\/remoteEntry.js&#8221;<br><code>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/code><\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>If our project had another name, we would change this too<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">remotes: {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; anotherName: &#8220;anotherName@http:\/\/localhost:4001\/remoteEntry.js&#8221;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import RemotePage from &#8216;anotherName\/RemotePage&#8217;<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>And that&#8217;s it! Just rerun both projects and you should have a functional MFE project with a Home page and a Remote page, running on another project and imported at runtime.<\/p>\n\n\n\n<p>With this basic example running, it&#8217;s really easy to spot the advantages of this approach. If you change the <strong>RemotePage.jsx<\/strong> file (and assuming there are no errors) you&#8217;ll notice that all it takes on the Host&#8217;s side to get the new version is refreshing the page.<\/p>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Error Handling.<\/h2>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>The problem is that things don&#8217;t run well 100% of the time. Sometimes the MFE team makes a breaking change or the Remote crashes and everything falls apart. You can replicate this behaviour by stopping the <strong>remote<\/strong> process.<\/p>\n\n\n\n<p>As good as this is, there is still room for improvement. The whole point of this is reducing bundle sizes and having different teams work on each MFE, but so far we haven&#8217;t reached this level of improved workflow and deployment.<\/p>\n\n\n\n<p>We can take advantage of React&#8217;s <strong>Lazy<\/strong> and <strong>Suspense<\/strong> to guard our host against errors from the Remote, and make the whole application more robust as a result.<\/p>\n\n\n\n<p>In order to do this, start by adding a <strong>SafeComponent<\/strong> in your <strong>host\/src<\/strong> directory, with the following code:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import React from &#8220;react&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">export default class SafeComponent extends React.Component {<br>&nbsp;&nbsp;&nbsp; constructor(props) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; super(props);<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; this.state = { hasError: false };<br>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">&nbsp;&nbsp;&nbsp; static getDerivedStateFromError(error) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return { hasError: true };<br>&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">&nbsp;&nbsp;&nbsp; componentDidCatch() {}<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">&nbsp;&nbsp;&nbsp; render() {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(this.state.hasError) {<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return &lt;h1&gt;Something went wrong&lt;\/h1&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.props.children;<br>&nbsp;&nbsp;&nbsp; }<br>}<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Then we&#8217;ll create a <strong>SafeRemoteComponent.jsx<\/strong>, also in the <strong>src<\/strong> folder:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import React, {Suspense} from &#8220;react&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import SafeComponent from &#8220;.\/SafeComponent&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">const RemotePage = React.lazy( () =&gt; import(&#8216;remote\/RemotePage&#8217;))<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">export default function SafeRemoteComponent() {<br>&nbsp;&nbsp;&nbsp; return(<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;SafeComponent&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Suspense fallback={&lt;div&gt;Loading&#8230;&lt;\/div&gt;}&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;RemotePage \/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Suspense&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/SafeComponent&gt;<br>&nbsp;&nbsp;&nbsp; );<br>}<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>This is the place where the magic happens. First, we lazy load our <strong>Remote<\/strong> page, which will grant us the faster load times when we open the application. Then, we use Suspense to display a fallback message in case the application takes a long time loading the remote (or can&#8217;t load it at all). Now we just need to add this to our Router, and it&#8217;s done:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p style=\"text-transform:capitalize\"><strong>host\/src\/App.jsx<\/strong><\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import React from &#8220;react&#8221;;<br>import ReactDOM from &#8220;react-dom&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import &#8220;.\/index.scss&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import { BrowserRouter,&nbsp; Routes, Route} from &#8220;react-router-dom&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import Home from &#8216;.\/Home&#8217;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import NavbarComponent from &#8220;.\/NavbarComponent&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">import SafeRemoteComponent from &#8220;.\/SafeRemoteComponent&#8221;;<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">const App = () =&gt; (<br>&nbsp;&nbsp;&nbsp; &lt;BrowserRouter&gt;<br>&nbsp;&nbsp;&nbsp; &lt;NavbarComponent \/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;div className=&#8221;text-3xl mx-auto max-w-6xl&#8221;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;div className=&#8221;my-10&#8243;&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Routes&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Route path=&#8221;\/&#8221; element={ &lt;Home \/&gt;}&gt;&lt;\/Route&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;Route path=&#8221;\/remote&#8221; element={<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;SafeRemoteComponent \/&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&gt;&lt;\/Route&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/Routes&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/div&gt;<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;\/div&gt;<br>&nbsp;&nbsp;&nbsp; &lt;\/BrowserRouter&gt;<br>&nbsp;&nbsp;&nbsp; );<\/p>\n\n\n\n<div style=\"height:20px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-cyan-bluish-gray-color has-text-color\">ReactDOM.render(&lt;App \/&gt;, document.getElementById(&#8220;app&#8221;));<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Now, if you rerun Host you&#8217;ll see a more pleasant &#8220;Something Went Wrong&#8221; message in the remote tab instead of a hard crash:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<div class=\"wp-block-uagb-image uagb-block-60f950b8 wp-block-uagb-image--layout-default wp-block-uagb-image--effect-static wp-block-uagb-image--align-center\"><figure class=\"wp-block-uagb-image__figure\"><img decoding=\"async\" srcset=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/react-bootstrap-image-micro-1.jpg \" src=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/react-bootstrap-image-micro-1.jpg\" alt=\"\" class=\"uag-image-43256\" width=\"\" height=\"\" title=\"\"\/><\/figure><\/div>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>And now with no error:<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<figure class=\"wp-block-image aligncenter size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"895\" height=\"594\" src=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/react-bootstrap-image-remote-page-1.jpg\" alt=\"\" class=\"wp-image-43257\" srcset=\"https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/react-bootstrap-image-remote-page-1.jpg 895w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/react-bootstrap-image-remote-page-1-300x199.jpg 300w, https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2022\/10\/react-bootstrap-image-remote-page-1-768x510.jpg 768w\" sizes=\"auto, (max-width: 895px) 100vw, 895px\" \/><\/figure>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\">Wrapping up.<\/h2>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>In this example we&#8217;ve build a simple web application using React, Tailwing and Webpack to take advantage of its Module Federation technology. This is only a starting point, there is still much more to discover and experiment, such as combining different Frontend frameworks in the same Host, or synchronizing state between the Host and the Remotes.<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p>Happy coding \ud83d\ude42<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p><strong><strong>Jo\u00e3o Oliveira<\/strong><br><\/strong>Software Developer at Polarising<\/p>\n\n\n\n<div style=\"height:30px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<p class=\"has-small-font-size\"><strong>Sources:<\/strong><br><a href=\"https:\/\/www.youtube.com\/watch?v=lKKsjpH09dU&amp;ab_channel=freeCodeCamp.org\" target=\"_blank\" rel=\"noopener\">https:\/\/www.youtube.com\/watch?v=lKKsjpH09dU&amp;ab_channel=freeCodeCamp.org<\/a> (freeCodeCamp.org. (2021, November 10). Micro-Frontends Course &#8211; Beginner to Expert [Video]. YouTube. Retrieved August 23, 2022)<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This tutorial is a follow up to my previous Micro Frontend (MFE) article, which tackles the basic &#8220;What, Why, How&#8221; questions of MFEs. The goal is to provide a simple use-case that serves as a launchpad for you to start using Micro Frontends through Module Federation in your projects. Generating the projects. In order to [&hellip;]<\/p>\n","protected":false},"author":41,"featured_media":41280,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"default","ast-site-content-layout":"","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"default","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-gradient":""}},"footnotes":""},"categories":[4],"tags":[],"class_list":["post-43168","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-technology"],"uagb_featured_image_src":{"full":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured.jpg",1600,900,false],"thumbnail":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured-150x150.jpg",150,150,true],"medium":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured-300x169.jpg",300,169,true],"medium_large":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured-768x432.jpg",768,432,true],"large":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured-1024x576.jpg",1024,576,true],"1536x1536":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured-1536x864.jpg",1536,864,true],"2048x2048":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured.jpg",1600,900,false],"authorship-box-avatar":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured-150x150.jpg",150,150,true],"authorship-box-related":["https:\/\/polarising.com\/techinside\/wp-content\/uploads\/2021\/05\/recruitmentprocess_image_featured-70x70.jpg",70,70,true]},"uagb_author_info":{"display_name":"Jo\u00e3o Oliveira","author_link":"https:\/\/polarising.com\/techinside\/author\/joao-oliveira\/"},"uagb_comment_info":0,"uagb_excerpt":"This tutorial is a follow up to my previous Micro Frontend (MFE) article, which tackles the basic &#8220;What, Why, How&#8221; questions of MFEs. The goal is to provide a simple use-case that serves as a launchpad for you to start using Micro Frontends through Module Federation in your projects. Generating the projects. In order to&hellip;","_links":{"self":[{"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/posts\/43168","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/users\/41"}],"replies":[{"embeddable":true,"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/comments?post=43168"}],"version-history":[{"count":28,"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/posts\/43168\/revisions"}],"predecessor-version":[{"id":43267,"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/posts\/43168\/revisions\/43267"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/media\/41280"}],"wp:attachment":[{"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/media?parent=43168"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/categories?post=43168"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/polarising.com\/techinside\/wp-json\/wp\/v2\/tags?post=43168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}