Microfrontends

Louis Q
2 min readOct 23, 2018

Decomposing a monolith into microservices brings great agility and speed for a development team, providing it is done well. But what about the front end? Can microservice principles be applied in the complex land of Babel, React, Vue, Angular etc? How do you get away from having a monolith front end talking to a suite of microservices? The answer? Microfrontends.

There are several frameworks to do this but by far the easiest way is to do it simply yourself.

Scenario: you need to render a funky graph which uses a graphing library but your customers may never get to that part of the user journey so why load the graph and its dependencies when they get to your home page? Now code splitting is an option here but what if the graph is shown in multiple apps and a particular dev team in your organisation wants to manage this functionality and provide updates to it without waiting for a release of the parent application? The solution I’ve gone for is to have the graph served up from its own service.

The child application

Define a function which is written into the global window namespace which renders your code:

import '../assets/styles/common/index.scss';import React from 'react';import Graph from './graph';
window.YourGraphFoo = {
load: (elementId, graphOptions) => { const rootEl = document.getElementById(elementId); window.ReactDOM.render(<Graph {...graphOptions} />, rootEl); },};

From my experience its not practical for every microfrontend application to run and bundle its own version of React, so to ensure only one is loaded from unpkg.com I tend to use this webpack plugin in the app which loads in all the microfrontends. It is also useful in that it excludes it from the bundle:

new DynamicCdnWebpackPlugin(),

Bundling up the graph for export from the microfrontend

In my webpack config I define the following to export in one bundle my code and the graph library:

entry: { myGraphCode: [path.join(__dirname, 'src/index.js'),  'recharts'],},

Loading the microfrontend in the parent application

First off its time to make a simple ajax call to get the js bundle from the microfrontend:

// I call /app which is an express route in the microfrontend
// to serve the JS
axios({ url: `http://yourmicrofrontend/app`,}).then(res => { loadExternalJs(res.data); // now run the function in the global namespace window.YourGraphFoo.load( 'graphDiv', this.graphOptions() );}).catch(() => { ...});

Note below how I inject the code into the dom:

function loadExternalJs(js) {  const script = document.createElement('script');  const textNode = document.createTextNode(js);  script.appendChild(textNode);  document.body.appendChild(script);}

and that’s it! Of course you can show a spinner et al but you’ve now loaded and rendered a microfrontend into a div from a parent application, you’ve given a front end development team (perhaps located somewhere else?) the autonomy to make changes without bothering you and you’ve started to break up your front end monolith.

Enjoy

--

--