Micro Frontend Architecture and Best Practices

October 17, 2018 

Micro Frontend Architecture and Best Practices

What is Micro Frontend?

Micro Frontend is a Microservice approach to the frontend web development. The current trend is to build a single page, a powerful and feature-rich browser application, which works on top of a Microservice Architecture. When working on a big application, it's difficult to maintain the content and to work. It is called Frontend Monolith. To get rid of it Micro Frontend is introduced.


How Micro-Frontend works?

Micro frontend architecture is an approach to develop modern web application as a composition of small frontend apps with multiple teams using different. Instead of creating a large Monolith frontend application, the application divided into domain-specific micro frontends, which are self-sustaining, developed and deployed independently.

Micro Frontend Techniques, strategies and recipes for building a modern web app with multiple teams using different JavaScript frameworks.

The idea behind Micro Frontends is to create a website or web app as a combination of features which are maintained by independent teams. Each team has a distinct work or mission it cares about and specializes. A team is cross-functional and develops its features end-to-end, from the database to user interface.


Benefits of Micro-Frontend

Every day a new JavaScript technology is invented, and these are increasing faster than a speeding bullet. That sometimes it can be frustrating as every JavaScript technology has its pros and cons. And while selecting a particular technology, everyone considers the minimum risk and max benefit. Here a micro frontend can help to use different technology for different services.

Here are some benefits of Micro Frontend -

  • Highly Scalable and Upgrade
  • Faster Development and Deployment
  • High Resilience
  • Better Maintenance
  • Support code and style isolation
  • Uses browser native’s API

Why Micro Frontend Matters?

In Modern Era, new web apps, the front end is becoming bigger and bigger, and the back end is getting less important. Most of the code written on the frontend. And the Monolith approach doesn't work for a more extensive web application. There needs to be a tool of breaking it up into smaller modules that can act independently. The solution to this problem is Micro frontend. Micro frontend code written only in pure JavaScript and any of the Javascript frameworks used or migrated from one framework to another.


How to Implement Micro-Frontend?

To implement the Micro frontend, let's start with the Reactjs app example.

It is good when the web app can evolve independently so that changes to the element can be introduced without being blocked by others and without breaking others as well. That's why in this example new app react app is needed that can be built, run, and deployed separately, treating others that have to communicate with it as services.

The example below is creating a header for a web page. For this example, ReactJs will be used, because why not? The modern generation is using it nowadays. Let's use create-react-app for fast bootstrap:


npm install -g create-react-app

create-react-app head

cd head/
npm start

Now let's add server-side rendering real quick, It will be used later when joining apps, for SEO and performance reasons. It is easier to attach this at the beginning, where we are than later.

First, let's change src/App.js to seem like an actual header:


import React from 'react';
export default () =>

<h3>Logo</h3>
<nav>
<ul>
<li>About</li>
<li>Contact</li>
</ul>
</nav>

Then, create a file called server.js at the root of the project that will start an express server and server-side render react -


const path = require('path');

const fs = require('fs');

const express = require('express');

const React = require('react');

const App = require('./transpiled/App.js').default;

const { renderToString } = require('react-dom/server');

const server = express();

server.get('/', (req, res) => {

  const htmlPath = path.resolve(__dirname, 'build', 'index.html');
​
  fs.readFile(htmlPath, 'utf8', (err, html) => {

    const rootElem = '

<div id="root">&#39;; const renderedApp = renderToString(React.createElement(App, null)); ​ res.send(html.replace(rootElem, rootElem + renderedApp)); }); }); server.use(express.static(&#39;build&#39;)); const port = process.env.PORT || 8080; server.listen(port, () =&gt; { console.log(`App listening on port ${port}`); }); </code></code></code></code></code></div>

So, to explain very quickly, this script takes root to react element (App), renders it to a string, and push it into the HTML before serving it to the user. React will later mount on top of that already rendered component.

But, that runs on NodeJS, and NodeJS doesn't understand JSX or other newer syntaxes like import, so babel will be used to transpile it before running the server-


npm install --dev babel-cli babel-preset-es2015

Now just add two tasks on the scripts section in package.json to run that -


"transpile": "NODE_ENV=production babel src --out-dir transpiled --presets es2015,react-app",

"start:prod": "NODE_ENV=production node server.js"

That's it, Now run the header with -


npm run build

npm run transpile

npm run start:prod

Best Practices of Micro-Frontend

There are three main implementation approaches.

  • Component Libraries - Depending on the stack of the main app the different components and app sections can be developed as libraries and “required” into the main app, the main app is a composition of various components.
  • Web Components - Web components are native implementations of the components included in the app such as menus, forms, date pickers, etc. Each component developed independently, and the main app project utilizes them and composes the final app.
  • Iframes - The most robust implementation also isolates the runtime environment of the components and app sections so each section can be developed independently and be agnostic go other sections’ technologies - i.e. develop some sections in React, others in Angular and more in vanilla Js or any other technology. So long as the iframes served from the same origin, inter-frame messaging is pretty straightforward and powerful.