Understand What Micro Frontends are and Why Module Federation is Useful
The idea behind micro frontends is to think about a website or web app as a composition of features which are owned by independent teams. Each team has a distinct area of business or mission it cares about and specialises in. A team is cross-functional and develops its features end-to-end, from database to user interface.
Micro Frontends 101
Micro frontends are an emerging architecture inspired by microservices.
Building with micro frontends is a modern strategy for deconstructing a monolithic codebase into smaller parts, in an effort to increase the autonomy of each team and the delivery throughput.
Each part can be considered a micro frontend, which will be deployable independently of the others.
Before deconstructing the monolith, you should choose the right approach to split your pages. This is useful to understand better and segregate the domain of your application (e.g. login page, private area…).
The most common approaches are vertical split (page-based) and horizontal split (parcel-based).
Micro Frontend Approach: Vertical Split
A vertical split approach is the easiest as it allows you to have only one micro frontend at a time on each page.
This results in the closest developer experience to a Single Page Application in terms of tools, patterns, and best practices, which remain the same.
Micro Frontend Approach: Horizontal split
A horizontal split allows you to have multiple micro frontends at a time in each view.
Usually, it is the most common strategy in business domains with multiple reusable parts.
Micro Frontends Composition
Once you have chosen the right split strategy and created your micro frontends, there is one last thing to do: decide how to compose them.
The available techniques are client-side, edge-side, and server-side.
Composing Micro Frontends: Client-side
In client-side composition, each micro frontend is dynamically assembled by the client (e.g. the browser).
this example uses a horizontal split with client-side composition;
each package in the monorepo has been generated using create-react-app and then extended with craco to override the Webpack configuration using a dedicated plugin that reads and applies the module federation configuration of each package;
although the provided code is organized as a monorepo, the same idea works with multiple repos or any other kind of development strategy;
each federated module can be used as an independent React application.
We are sure this is a host because we are defining just the remotes to import. Please also note the absence of the filename configuration;
it loads its dependencies from a remote called components, which entry point is reachable at the address http://localhost:3001/components.js;
each dependency defined in the package.json will be shared with the other federated modules.
Additionally, we ensure that a specific version of react and react-dom are instantiated just once.
In the end, this is what the user will see:
Module Federation: the Trade-Offs
Applying module federation we have found some trade-offs, which will be explained below:
Exposing parts of the application in such a dynamic way allows us to have:
faster builds as there is less code to process inside a single package;
more rapid deployments because there are fewer artifacts to release;
more immediate rollbacks because we only have to re-expose the old federated artifact to deploy an old version of the application.
Module federation is a panacea that can be used everywhere, you must know the shape of your application really well to apply it correctly.
As you can see, it also requires a little bit of configuration, which might not be so familiar to developers that have always worked with SPA.