Microservices frontend: module federation, an handsome promise

Over the last couple of years, the benefits of micro-service architectures have been well publicized. Starting from monolith architecture at the dawn of web, we relentlessly and progressively broke them down into smarter, smaller units of features called micro services. The whole backend world embraced this model.

Major breaking changes from monolith and benefits are:

  • Product teams empowerment and enablement

In the end, we have an elegant decentralized backend stack. But how can we take care of our massive front end monolith ?

Photo by Shane Hauser on Unsplash

I’ll take here a real life scenario. Cdiscount scenario (Cdiscount is a french 4.5B$ e-commerce platform handling 1B yearly unique visitor).

Before we start, here are some utterly important considerations:

  • Front-end Caching: Maybe speaking about caching and front-end sounds awkward to you (it certainly did to me initially). But in real life, there is simply no way to avoid it at a descent scale (both traffic and software). So, let’s be it, we will talk about caching at the front-end side …

Let’s say, you’re a big company, with a lot of employees and teams. You’ve got one or multiple sites in React / Angular / Vuejs; with SSR.

And of course you have a nice micro service stack for the back-end with dedicated teams for each asset of your system. (Product / Price / Cart / Checkout and so …).

At the front end side, you are basically facing the following challenges:

  • Releases crashes: Without Canary Release, one release can crash the all site. So Continuous Delivery is just too dangerous. This architecture issue deeply impact your change fail rate (cf Accelerate).

Microservices Front-End

As pre-read material, I would recommend Martin Fowler post on micro service front-end. (like many times with Martin, this is spot on): https://martinfowler.com/articles/micro-frontends.html.

Photo by Ryoji Iwata on Unsplash

Several solutions claimed to resolve this problem the past few years:

Pure npm

The first approach for sharing code, is npm and package handling. This solution doesn’t resolve all the major problems because, at the end of the day, you are still stuck with a monolithic approach. No independence at core, you’ll have to modify all callers (but I wanted to mention it because this is the first natural way that comes to mind)

Client side only frameworks

Also, I am not interested in this solutions, because SSR and SEO/Perf is mandatory in a real world scenario. We want a universal full stack solution.

Micro SSR

Micro SSR is the concept of building a single page with several different front end apps.

  • A major actor on this type of architecture is mosaic (Zalendo).

Mosaic addresses this issue by using Fragments that are served by separate services and are composed together at runtime according to template definitions.

Other similar approaches:

Micro SSR in details

Each micro SSR or MFE is an application (in a front-end way; e.g. a React App). Each app is composed by two artifacts:

  • SSR endpoint (Node js instance, isomorphic technique)

Note about bundling: each app is, at core, a Webpack transpile/bundling ; and doesn’t have to know each other, each Webpack is self-contained.

At the top level, we have an orchestrator which aggregates all SSR outputs and bundles them together to deliver a page. Some people developed it in React, for SPA convenience; others in Nodejs core (cf mosaic: Tailor), but independently of the chosen language, the problems are about the same.

SSRMFE architecture

In this schema, ORCH aggregates all the DOMs served by SSR / caches.

CACHE, could be applicative caching or reverse proxy (varnish, …)

I have drawn several BFF, but it could be just one. In fact we want to have a vertical stack, so this is a coherent choice.

This approach has some strengths:

  • Multi CPU on executions

Bundle injection

Here, a MFE is composed by only one artifact: the source code, in Webpack terms, a bundle. We could see that technique like dynamic npm packages (even if bundling is not that coupled) but without versionning, and so, all the pull requests associated.

Principle is pretty simple, a front end code in javascript (SSR or not) will ask to the component to load a manifest.json (json generated by Webpack which specifies all dependencies and gives CDN hosted urls), then js will insert in the document DOM all the <script src=”xxx” /> tags. By this way, the loaded remote will have all of its dependencies and will execute.

The main difference with micro SSR is that we share code. And when sharing code, we still have a monolith (from server/CPU point of view), but code is dynamic. Releasing MFE will be dynamic on every depending host.

So, no multi threading here. (only one execution: the host execution)

Cf really good example by Monica Lent. Screencast and host repo: https://youtu.be/Td7w0_nD5_4 and https://github.com/mlent/microfrontends-host

R&D subjects: all envisioned solutions

Several points are R&D subjects:

  • Sub MFE: a MFE which call another MFE. This is a real performance issue. To know if a MFE is contained in another, we have to wait the return of the first container. Complexity can be really tricky. In the micro SSR schema, I’ve mentioned a prefetch (prefetches subfragment), this could be a solution but a difficult one. Note : Mosaic and Tailor simply said no to this feature. Note 2 : cf Cdiscount’s CTO quote at the end ;)

Module federation

Passed all this pretty complex considerations on MFE and the solutions out there, here comes Module Federation.

Photo by Clark Tibbs on Unsplash

First of all, module federation will be included in webpack 5.

Zack Jackson, the co-creator, describes it like this:

A scalable solution to sharing code between independent applications has never been convenient, and near impossible at scale. The closest we had was externals or DLLPlugin, forcing centralized dependency on a external file. It was a hassle to share code, the separate applications were not truly standalone and usually, a limited number of dependencies are shared. Moreover, sharing actual feature code or components between separately bundled applications is unfeasible, unproductive, and unprofitable.

This is in development, as we speak. And we already see a powerful and agnostic technology. Webpack 5 will be a fantastic breaking change in front end architecture.

The promise here, is to share code. AND sharing is done by Webpack.

  • The first important thing in my opinion, is the keyword Webpack. Yes, all the Webpack jobs will know themselves and will be able to share between them. The promise in itself is a revolution. It can solve the performance and sharing problem naturally, in an elegant way.

But, for me, the real hard work, on this, is the library sharing part. And module federation is about this. It can at runtime elect versions - have a dependency resolution - and this is a real big thing.

Automatic module sharing (i have this in v2 of webpack-externral-import but the rewrite (v3) for Webpack changed my approach. So ill be re-implementing this

Tree-shaking support - FederationPlugin - if sharing a module from host to remote likely shouldn’t tree shake the module. However ill be writing another extension and hook for SharedModule which will enable dynamic export hydration. The idea is that you can merge exports between two builds. Thus offering tree-shaken, shareable code. This required some additional work outside the scope of my proposal to Webpack.

All the boilerplate code we have been writing to make MFE work (redux states, reat custom hydratation, etc ..) are not needed anymore due to Webpack integration.

  • Sub MFE: ✅ : bidirectionnal remotes is the module federation answer.

Here: https://github.com/module-federation/module-federation-examples you’ll see some use cases and code exemples:

For now there are a few downsides:


  • Module federation is really young, it is really beta, and developers are going to find lots of use cases. It is clearly a thing to watch.



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store