Microfrontends with Webpack Module Federation, React & Vue

Web Development
A microfrontend web application that combines separate React.Js and Vue applications in one frontend with the help of Webpack Module Federation.
Test and Deployment on github with github actions and hosted on aws CloudFront.

Overview

One of the big challenges we face when working with Web Frameworks certainly is the fast development of the JavaScript Ecosystem. What is state of the art today might be obsolete in the not too far away future. Feature rich and powerful web applications (single page apps typically) tend to grow and to become complex front-end monoliths that can be difficult to maintain. If – over the time – new technologies arise and web front-ends shall be refactored this can lead to quite some headaches. Also integrating third party apps or new web applications that were developed in-house by another team can be a big challenge.

Microfrontends with Webpack Module Federation, React and Vue

Microfrontends treat web sites and web applications more like a composition of features or smaller apps which are owned by different instances / independent teams that might have different backgrounds (different specialization, business area, technologies, …).

This approach, while still controversial, opens up a lot of great opportunities to either successively refactor applications and migrate them step by step from one framework to another, or to integrate third party apps or apps developed by other teams of the same company.

More detailed Information on Microfrontends can be found here:

The React applications

The React Part of the web application consists of a few independent React applications with distinct areas of concern. Each of them is developed separately and lives in its own project folder.
One app for providing a login dialog, one wrapper application, and one application for rendering articles and pricing information.

The Login application

The login app renders a simple login dialog and provides a global login state for all the other applications.
The login state is distributed across the various applications via a shared state object. This object is passed to the other applications by webpack and that can be used by those apps regardless how they were implemented (react, vue, ...)

Microfrontends with Webpack Module Federation, React and Vue

Wrapper Application

There is one wrapper application that holds the global shared state and handlesthe routes to the different applications

Articles and pricing

A React application that displays articles from an exemplary online shop with pricing information. This application uses its own application wide state for he articles etc and in addition it receives the login information from the wrapper component. The Articles and pricing information components were styled with bootstrap and they fetch their data vie ajax from a REST API.

A Vue Dashboard

One of the tasks was to provide administrators with a nice and clean dashboard in which the most relevant data of the pricing application could be visualized so that privileged users can get a quick overview on the current state of the application data and it’s history in a chart.

There are of course also quite a few dashboard templates in React but the Vuetify Dashboard Component was the preferred choice for its clean look and its great extensibility.

The challenge here of course was the fact, that this is a Vue and not a React Component like the rest of the frontend. But with the help of a microfrontend approach and a clear separation of concerns, it should be possible to create a sub application in vue and to integrate this into the rest of our frontend.

A dashboard made with Vue and vuetify

Following the general ideas and philosophy or microfrontends, I developed the dashboard application independent of the rest of the frontend apps, like a separate team or third party would do and just defined the necessary data that I would need from “somewhere else” (the login state for example) as my API for the dashboard application.
The data for the dashboard can be fetched via ajax, if the user has the permissions to do so (login state) and the application should not be accessible if privileges are missing.
This should be catched in the wrapper component (routing etc.) but also in the dashboard itself, in case a user tries to access the dashboard in other ways.

Module Federation

So far we just have a bunch of React applications and a Vue app. That is all fine but the real magic happens with Webpacks Module Federation Mechanism.
As complicated as handling state between the different applications can get and as sophisticated the UIs might become, the underlying mechanism provided by webpack ist surpringly relatively simple and easy to understand. And I think there lies some of it’s beauty.
So, essentially Module Federation allow a JavaScript application to dynamically run code from another application and even share dependencies. For example if two of your React applications in a micro frontend web application use a library like moment.js they could share this dependency and webpack would just load this bundle once for the client.

To be able to load code from other apps, there is some container orchestration in the webpack config files necessary. The applications from which we want to load code have to be registered as “remotes” in the config files. After that we can use dynamic imports to load the code. So actually pretty straightforward.

A brilliant and comprehensive article on module federation can be found here:
https://medium.com/swlh/webpack-5-module-federation-a-game-changer-to-javascript-architecture-bcdd30e02669

Talk is cheap. Show me the code.”

– Linus Torvalds

Check out the Source Code

Sometimes things are easier to understand when looking directly at the code. Especially complex topics like webpack module federation where multiple sub projects interact with each other

You can find all the source code for this project on my github:
https://github.com/peter-siebold/microfrontends

Under microfrontends/packages/container/ you will find the wrapper application and within the /config folder in the webpack.config files you find the remotes entries for the dynamic imports that are used in the wrapper application to include all the other apps

Conclusion and final thoughts

Conclusion I worked on this project a couple of months ago when I was researching different possibilities and ideas for refactoring the web frontend for an enterprise level software solution.
Here my main focus was to find a solution that would leave us the option to either switch frontend technologies successively and migrate from one library or framework to another if needed or to allow third party development teams to work on projects independent on their front end tech stack.
I checked a few different approaches for microfrontends but so far I found module federation the most elegant solution.
It is a bit complex at the beginning to set up everything proberly but once you get a hang on it, things become relatively easy.
I can only recommend to check out this interesting piece of technology.
  • JavaScript
  • React
  • Vue
  • Webpack
  • microfrontends