Making frontend apps manageable and independent
If you have been following the frontend community for some time, you will notice quite a lot of attention towards the term “Micro-frontend”. More and more solutions are trying to support this architectural approach. It’s about splitting a front end app up into individual and independent “micro frontend apps” that are working together.
Why do that?
Because this can help you to make large projects more manageable and help when transitioning from legacy software solutions.
In this article, I want to explain to you in more detail what micro frontends are and how they can be of benefit to you.
Micro-frontend architecture is a new architectural design approach in frontend software development. In this approach, an entire frontend application is split into individual micro frontend applications that work together. As the name suggests, the concept is inspired by the architectural concept of microservices.
According to Micro-Frontend.org:
“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 a distinct area of business or mission it cares about and specializes in. A team is cross-functional and develops its features end-to-endfrom database to user interface”.
Some benefits are:
- Architectures may become easier to manage.
- Developer teams can cooperate and work independently on one frontend.
- The approach can help in migrating from older to newer applications.
- Independent deployments are possible.
- Clear contracts.
- Easier to add, change, or remove any code.
- Easy to test.
Right now, there is not one clear way of implementing this approach. Also, there is no framework or library that sticks out as the go-to strategy. Therefore, depending on your requirements and restrictions, there are multiple ways to go about it.
A simplified look
Here you can see an example using HTML markup of how these micro frontends could be integrated. The layout can differ based on your requirements. Whether they are used as a navigation header, side to side or, as in this example, simply on top of each other. The micro-frontend is a custom component in the framework used to represent an example implementation.
What does the micro-frontend component do? It simply renders an iframe.
The iframe HTML element is very useful in the context of micro-frontends because they provide very solid sandboxing behaviour.
However, there are also some issues one has to think about:
- The CSS is entirely isolated in an iframe.
- The back button of the browser will not work in terms or preserving navigational states of inner iframes.
- For communication between the iframes, one has to look at the CORS setup and might need to use postMessage.
- The entire authentication across subdomains, iframes will need to be managed.
- The iframes will need to load their respective scripts etc. that speed limit might be met with SSR.
Embedding without iframes
Now, when it comes to including micro-frontends without iframes there are also two approaches:
- Include them directly inline in the page’s HTML via Tags.
- Place them in the shadow DOM.
The inline and shadow DOM methods differ mostly when it comes to CSS. CSS will be entirely encapsulated in the shadow DOM. In the case of inlined, all CSS would be shared throughout the entire page.
Just as a note — applications built using frameworks like Angular, React, or Vue are likely to have trouble living in one document altogether or exclusively in the shadow DOM. For those, we might want to stick to iframes.
The micro frontend server will serve an entire HTML page. Now that is trouble! We cannot insert the
body tags into the application without breaking things.
This can be solved by using the template tag as a wrapper in which the micro-frontend content is served from the server.
Modern browsers can parse a template tag without executing it.
In doing so they remove invalid content such as the
<body> tags, while preserving their inner content. So the
<link> tags in the
<head>as well as the content of the
<body>, are preserved. This is exactly what is needed to insert the applications.
There are different ways of micro-frontend architecture but these are the major steps:
- Defining micro-frontend apps in your application.
- Composition of micro-frontends.
- Routing the frontends.
- Communication between the frontends
1. Defining a micro-frontend
It is important how you define your micro-frontends. The division of your app based on logic or business is key.
You can use logical responsibilities like a product profile or recommendations view of products that are developed by one team. On the business side you can split the responsibilities based on the entire domain logic. For example a marketplace or news page.
2. Composition of micro-frontends
There are several ways for composing micro-frontends:
- 1. On the Client: All the apps are composed and bundled at the initial build time.
- 2. On the Server: One frontend container is loaded and all the micro-frontends are loaded upon request from servers.
- 3. On the Edge: A CDN assembles the views. The CDN providers allow you to use Edge Side Includes (ESI).
3. Routing of micro-frontends
Routing will depend upon the type of composition you choose.
Using server-side composition, the routing happens through the server.
With edge-side composition, the CDN assemble the frontends via defined inclusion. In client-side composition, the micro-frontends are loaded based on the state inside the app.
4. Communication between micro-frontends
Just like routing, the communication layer between micro-frontends depends highly upon the type of composition you choose.
The goal is to message other micro-frontends about user interaction.
To ensure different teams are loosely coupled and to benefit from independent deployment, communication needs to work on a layer where the frontends should be unaware of each other.
- Event bus and event emitter — One approach is to use a shared component with an event bus and inject it inside all of the micro-frontends.
Another approach would be to use custom events.
This is highly flexible as the payload includes the identifier of an event and a custom object. Since these events are dispatched via a common window, all our micro-frontends have access to it.
- Using web storage — If all our micro-frontends are within the same subdomain, we can store and access data through cookies, sessions, and local storage.
- Query string — A query string as part of the URL can be used to pass data and access it in micro-frontends. This one is quite inefficient.
Here are some popular frameworks for creating micro-frontends:
- Module Federation
In this article, I tried to show you what Micro frontends are and what the benefits of implementing this architectural approach could be.
Interest, the same rule as with microservices applies.
Check your requirements and restrictions and whether the organizational implications will benefit you. Then Micro frontends can be a beneficial approach to independent and individual frontends.