Micro Frontends for UI
Image Reference : https://noti.st/naltatis/HxcUfZ

Micro Frontends for UI

What and Why of Micro-frontend

The Microservice architecture is not a new pattern anymore for the backends. The modern application architecture has embraced this pattern for the cloud native backend platforms. We do not see this principles applied, when it comes to building UI. React-Redux combination is a strong way to separate the view and controller logic on the UI layer, however, there is a growing need for teams to build independent UI apps those can be developed by separate teams and collaborated later to create new experience. Essentially,

UIs are becoming monoliths and we need to extend the microservice ideas to the frontend development.

This article mentions the major steps involved in building micro-frontend systems through a sample app. It also talks about important steps around Webpack and CSS to realize true benefits of this technology.

No alt text provided for this image

Sample Application

The sample application supporting this article can be accessed at https://d4e2yqa5hvu3s.cloudfront.net. This is the AWS cloudfront public URL that serves the built project through S3. (No need for any EC2 instance!)

No alt text provided for this image

The application is made up of three different standalone UI projects (called micro-frontends) and a host project (container) that serves this micro-frontends. The purpose is to just demonstrate how different front ends can be integrated. I have not implemented the actual backends (dummy data only).

  • The home page displays first micro-frontend (Marketing)
  • Click on the 'login' on the top right corner to navigate to Auth micro-frontend
  • Click on the signin button.(no real userid/pwd required), this takes you to the dashboard micro-frontned.
  • You can click on the 'App' on top left corner or Click on 'logout' to go to the home page.

The code for this app is at https://github.com/jaysara/micro-frontends. This github has .github/worklfows directory. This demonstrates how CI/CD is implemented for this project. The CI/CD for this project builds all the micro-frontends projects, deploys them to S3 bucket and invalidates the cloudfrontend cache.

Project Setup & Frontend Integration:

The sample application does not have a real data served by the backend as this article concentrates more on how UI integration for different micro-frontends can be built. Integrating different micro-frontends to collaborate in one application is a critical piece of micro-frontend pattern. There are three main type of known integration patterns when it comes to micro-frontends. There are three known patterns of integrating micro-frontends.

  1. Build-time Integration : Easy to setup.
  2. Runtime integration (the sample application uses this)
  3. Server side- integration:

The Tooling and setup for both server-side and runtime integration are complex. This project uses runtime-integration. In my opinion, runtime integration is the most flexible and performant solution right now. It is little hard to setup as it requires good understanding of the Webpack.

No alt text provided for this image

All the projects are setup using simple JS app framework. (no react/angular or Vue framework). All the projects can be run in isolation (on its own). All the projects are integrated through container. This can be realized by running container app.

Module Federation Plugin

ModuleFederationPlugin is important plugin to consider while integrating micro-frontends. This plugin glues the micro-frontend apps with in the main host app.

ModuleFederation Plugin allows developers of the micro-frontend to specify, how a particular micro-frontend can be integrated with other apps.

Here are the steps to do that,

(1) Designate one app as host (in our case Container) and others as Remote (these are marketing, auth and dashboard in my example)

(2) In the remote project, decide which files you want to make available to other projects. (in our case it is -index.js for all the projects.)

(3) Set up "Module Federation Plugin" in the remote projects to expose the files decided in step-2.

No alt text provided for this image

(4) Setup "Module Federation Plugin" in the host to fetch the files decided in step-2.

(5) In the host refactor the entry point to load asynchronously

(6) In the host import the files you need from remote.

No alt text provided for this image

This architecture allows us to have Zero coupling between the container and child projects. No importing objects, functions, classes etc. No shared state between two applications.

Handling CSS in micro-frontends:

When we build applications separately on our own, we do not anticipate it in the context of other applications. We assume that all the CSS styles will not change during user navigation. This assumption can easily be wrong in the micro-frontends scenario as shown in the diagram below.

No alt text provided for this image

How to fix CSS ?

The above problem can be fixed if we generate a unique name for every class in CSS through our javascript. This is called "CSS-IN-JS" option. As shown in the picture below, you can write a javascript with a randomly generated class name. This will generate the css file with the random and (mostly) unique classname.

No alt text provided for this image

If you look at the Landing.js, I am using makeStyle function in '@material-ui/core/styles' This generates unique styles to the javascript class. This makes the CSS class unique as well. However this generated class is based on a number (e.g jss1, jss2, jss3 etc). This questions the uniqueness of the generated classname and can cause the collision with other micro-frontends. To avoid this, pass the productionPrefix value specific to the micro-frontend project you are in as shown below.

No alt text provided for this image

Verify the generated class names for class for all frontends are unique through devtools

No alt text provided for this image

Working with AWS-S3, CloudFront and CI/CD:

This UI is hosted in my S3 bucket and served by a public cloudfront on AWS. This has been a zero cost architecture for me so far. I created Github workflow that builds all the projects and publishes the final build file to S3. There are couple of things that may be important to mention when we build this kind of workflow. 

  • The access to S3 should be provided to Github for its to upload the file. aws s3 sync command is a good way to push the new files to S3.
  • The credentials required to log on to S3 are stored in my Github repository secrets that only I can see/alter. There are different plugins available in Github that allows you to pull these secrets from some kind of vault setup if needed.

The cloudfront does not automatically detect the change of file in the S3 bucket. As a result of new build, your S3 bucket may contain new files, however, cloudfront will still serve the old file from its cache. You must invalidate the cache in cloudfront everytime a new build is built.

No alt text provided for this image

You should always evaluate if this pattern is a right fit for you and your application. There are number of ways to build micro-frontends. I have shown one of them. Mostly, your requirements should drive the architecture.

Here are the important takeaways that I have from my exploration of this pattern.

Takeaways :

  • Always ask, if you have to change one app in the future, will you have to make changes to the other app. In my example, routing logic is a good example of this. I am using a simple generic interface. If we decide to change the routing library, we do not need to change other parts in the app. 
  • The Frameworks in UI have been changing more often. Few years from now, everyone may forget React(or something better will come up replacing it). Keeping application stack separate helps you modify one part of UI independent of others.
  • Don't forget to scope your CSS. The failure of doing so, can give you a different behavior in your prod than what you see in dev under individual micro-frontend.

I believe Micro-frontend pattern is here to stay and will evolve as more and more javascript frameworks get built. As the demand for full stack developers grows in the industry, this patterns helps developers to have equal design mindset for UI and the backend development. It allows them to apply same principles universally across different tiers of applications. APIs are developed predominantly for the backend/data services. This pattern will allow us to build APIs that serves UI. Let's call it AUI [Application User Interface] for now :-) !!

References :






Hi, Taking Stephen Grider's Udemy course content (https://www.udemy.com/course/microfrontend-course/?src=sac&kw=microfrontends) and presenting it as your own work without a reference to the creator is stealing. You even used his code and also the diagrams are taken from the course.

Like
Reply

Hi sir, this post is very helpful for me! And I have a small question. I have Shell App that does not have any CSS library but in another app (Sub App), I have bootstrap for styling. And when I imported a component from Sub App into Shell App, the class of bootstrap from Sub App didn't work in Shell App. How can I resolve that problem? Thank you for reading this comment, Sir!

Like
Reply

In an existing application (classic server-side monolith) how can we attach a microfrontend?  Should webcomponents be used to mount the remote application? In your article you had everything in frontend and the container managed it with webpack, if I didn't have this scenario, how could I do it? Thanks a lot and great article

Makes life easy for the support team. Awesome!

Like
Reply

Superb article.and very relevant these days

Like
Reply

To view or add a comment, sign in

More articles by Jay Saraiya

  • OpenAI AgentKit: A Practical Guide to Building an Enterprise AI Platform

    The last year has been all about agents — but until recently, building them felt like stitching together prompts…

    4 Comments
  • 🚀 Boosting Java Performance with Virtual Threads (Java 21+)

    Ever noticed your Java service slowing down under load — even though CPU and memory look fine? 🤔 Chances are, you’ve…

  • Turbocharging Spark ETL Pipelines for Massive, Wide Datasets

    The Challenge of High-Dimensional Data Processing Apache Spark is a powerhouse for big data processing, but when…

    1 Comment
  • Simplifying Local Deployment of Large Language Models using Ollama

    Over the past two years, generative AI has driven transformative changes across industries, reshaping how businesses…

    2 Comments
  • LangChain and LLM

    One of the biggest technical innovations that 2023 can claim credit for is the introduction of Large Language Models…

    3 Comments
  • Metaverse: Why should we pay attention

    Why Rebrand When Facebook changed its name to Meta, many people including the media ridiculed this move and looked at…

    10 Comments
  • Serverless functions on Multicloud

    Multicloud approach is becoming a popular architecture pattern on cloud platforms for many organizations. Many think…

    6 Comments
  • Value of Adopting Reactive Programming

    The years old problem that software engineering always thrive to solve is how do I handle more users in my system? As I…

  • Schema in Kafka

    Kafka is becoming a de facto messaging framework in microservices based systems. The important aspects in any messaging…

    1 Comment
  • Data Streaming Pipeline Architecture

    What is Data Stream: If you had to write a software to identify all the 'red' cars parked in a garage, it is a…

    3 Comments

Others also viewed

Explore content categories