Lerna & Module Federation for AWS micro-frontends

Antonio Lagrotteria
4 min readMar 21, 2022

--

This article concludes my mini-series dedicated to a complete AWS architecture for Module-federated micro-frontends. The first two parts consisted on below subjects.

  • A high level AWS architecture introduction
  • A CDK implementation

This final part will show how this Javascript application was implemented by using:

I recommend to have a look at this Github repo, which presents a wide list of implementations to see the plugin in action. For this app, I leveraged the dynamic host system host example.

MonoRepo setup

Our mono-repo contains all micro-frontends and their IaC in a single place, as shown below.

The repository consists of different parts:

  • React Micro-frontends (mfe-apps) folders containing their independent implementation. One of them (mfe-app1 or parent) is the application shell orchestrating the other two micro-frontends (here also called child apps).
  • A cdk folder including IaC components presented in second article.
  • Lerna and package json files for micro-frontends’ dependencies and bootstrap.

The app will result in below.

Lerna

Lerna helps organizing mono-repo as workspaces where you define apps into packages. First you should initialize your project by running below commands:

npm i lerna -g
npx lerna init

This will generate a lerna.json and a package.json.

  • In package.json you would fill typical dev and prod dependencies along with scripts such as:
“start”: “lerna run  — scope @dynamic-system-host/*  — parallel start”

Above command finds all packages whose name (aka scope) starts by “@dynamic-system-host” (later under Child Apps section).

  • In lerna.json you will specify type of npmClient used (either npm or yarn) and delegation to package structure to yarn by Yarn’s useWorkspaces.

The Child apps

The micro-frontends are very simple web app based on React and Webpack. You can check one example in below link.

There are only two peculiar features to mention in regards of Child apps.

Package name

By defining the package.json name field, you will instruct Lerna on what package to start (remember the scope parameter of the npm run start script).

Webpack Configuration

Module Federation plugin exposes the mfe-app2 micro-frontend to a remoteEntry.js which will bootstrap the App.js file as main entry point of the module.

It also allows to share libraries across micro-frontends. Typical case is that in a micro-frontend app, you would not want to load the framework specific libraries (e.g: React and React-dom) every time, but reuse it or being smart about it.

Below shows an extract of the webpack file for one of the child apps.

The App shell

The app shell serves as container for the other micro-frontends, but how does Module Federation literally make this happen? Micro-frontends can be defined as Systems:

Let’s look at them.

Script injection

When micro-frontends are rendered, a dynamic script gets simply injected in the HEAD tag of the page, via the useDynamicScript function. This script is the remoteEntry.js code generated by the Module Federation plugin, which allows us to load the micro-frontend.

React Lazy-loading and Suspence

The micro-frontend is loaded as a lazy component via the React.lazy. This renders a dynamic import as a regular component, supporting code-splitting. It requires a Promise which has to resolve to a Module being retrieved from a datasource or, in this case, the global window object.

Once retrieved, it will be initialized via the below loadComponent function and loaded via React.Suspence.

Mounting Systems

Systems are mounted by providing three properties:

  • A remote url, the remoteEntry url script exposed by Module Federation
  • A scope - micro-frontend identifier
  • A module, the entry module to be loaded

Abstracting micro-frontends as Systems allow better module federation definition and easier mounting strategy:

Conclusion

This article concludes my quest to try to demonize the Module Federation plugin and the complexity behind adopting module federated micro-frontends, and see how feasible and scalable is to deploy and host them on AWS Cloud.

It just touches the surface and I acknowledge the many challenges that adopting micro-frontends entail (trust me!), but I hope it makes you embracing this architectural style and trying out of it fits your organization. Hope you enjoyed this mini ride :-)

--

--

Antonio Lagrotteria
Antonio Lagrotteria

Written by Antonio Lagrotteria

Engineering Manager | Full-Stack Architect | Team/Tech Lead with a passion for frontend, backend and cloud | AWS Community Builder