One of the definitions of micro frontend that represents an excellent overview of its functionality is given by Luca Mezzalira:
"Micro-Frontends are the technical representation of a business subdomain which allows independent implementations with the same or different technology. Their main purpose is to minimize the code shared with other subdomains and they are owned by a single team"
When we start to analyze this definition, we see that micro frontend presents a business subdomain, meaning one domain which we can separate and completely implement on our own. Not every part of the application is able to work independently and be implemented separately, but there are some parts that we can use with the same or different technology (Angular, Vue, React etc.) depending on the need of the project or team who works on its implementation.
Additionally, it is important to minimize the code which is shared with other subdomains and also it is very important that a single micro frontend is owned only by one team which is responsible for it. This means that others can participate in its development, but it is important that the people that want to participate send a pull request, for example, so that that part of the project can be approved and accepted. In this case, the responsibility is shared, and the tasks are known and distributed amongst the team.
Is Micro Frontend Architecture Right for Every Project?
Just like everything else in project management, something that works for one project, does not necessarily need to work for another. At the beginning of any project, teams and organizations first need to answer questions concerning the development process and which development ideology will be followed, such as Agile or Waterfall. If we can start from there, we can anticipate how the project will be developed.
If there is a linear or a sequential approach, one team will be involved, the project does not show any tendencies to stray away from the scope, or there will be new functionalities, in this case there is no reason to implement micro frontend and change the architecture of the project.
On the other hand, if the project has an incremental and interactive approach, then it may be ideal to use micro frontend. In an incremental and interactive approach in developing process, there are usually many changes, including new requests and the development of new functionalities, which are necessary to be coordinated by many different teams.
The whole Agile Release train in the beginning is an excellent and very applicable solution in organizing a project and improving communication amongst the different teams. In practice, it happens often that dependencies exist amongst the teams, and it is important to communicate changes in a project to other teams to influence them to also implement and embrace those changes. This is super important especially in situations when different teams face challenges related to bugs and hotfixes, and everything can be sorted by priority and delegate the problem to a specific team to solve.
This process can be very frustrating, but it is necessary to communicate consistently and effectively. In my experience, there can be up to 150 or more people that are actively involved in the development of an application and lack of communication can be an impediment in scaling the project and the team. In all the above-mentioned situations, micro frontend architecture is something that can be very useful and that can relieve workload on the development process side.
Why Micro Frontend?
If we look at the development of BE and FE Monolite structure and horizontally organized teams, where the whole team is responsible for the development of complete BE or complete FE, a microservice architecture system has been introduced at BE since 2015, and the BE team is divided vertically where part of the team deals specifically with the development of only its part.
From 2020, we have these possibilities on the frontend as well, and we can implement it in various ways, through iframe, build-time integration, through other frameworks for micro frontend (Mozaik, Single-SPA, Piral). One of them is certainly an implementation through WebPack 5 and the Module Federation plugin.
A vertical structure of a team enables more teams working on a frontend to develop different parts of an application simultaneously and independently. In situations when the domain is complex it is simpler when the overall picture of the project is shown to all the members of the team and then delegate the tasks to each team member highlighting how their part contributes to the overall application.
Considering fluctuations in production and adding new teams during development, the onboarding process alone is simpler if somebody is aware of the part, they need to do rather than them knowing everything about the application.
Key Advantages and Reasons for Choosing Module Federation
The biggest benefits are:
Independent development and deployment – Even if the principal Domain Driven Design (DDD), which is mainly implemented in the backend, can also be implemented on the frontend when creating the micro frontend. This is done to make a better structure of the organization and to create efficient and independent teams. Time needs to be invested to sort the domain and subdomain and consequently create development teams. This will enable independent development and deployment of different parts of an application with different specialized teams. The team working on this, works in parallel on development. Of course, there are parts of an application which are not able to completely function independently and that is where communication and team engagement is extremely important.
Sharing a library which can update without rebuilding
It is a better way of sharing code
It solves the problem concerning dependency
Micro frontends implemented using Module Federation have many advantages. Few examples of when not to implement this solution:
Applications that are small do not require micro frontend architecture
Applications built in Angular 11 and older versions
Applications which do not use WebPack 5 as a module bundler
How to Implement a Micro Frontend Architecture Using Webpack 5 Model Federation
When the implementation of Module Federation is defined, i.e., if it is concerning a migration or a new project and it is predicated on the same premise, the following 4 items are important:
To define – Defining micro frontend – Make a subdomain and deciphering whether the teams will be vertically or horizontally divided and decide how the micro frontend will be delegated.
To compose – Understanding where we want to compose micro-frontends. There are three ways of how you can do that:
Depending on the needs of the application, we can coordinate what is needed. There is no real right or wrong choice.
Routing – Like composing, it is also important that it is client-side, server side or edge-side.
Communication – The important question here is deciding whether to work horizontally or vertically. Regardless of the micro frontend, there needs to be communication and exchange of information. The first what needs to be done is the event emitters through which we can protect the integrity of the micro frontend. So, every micro frontend emits some event and only those who follow that event will react in that specific way. There are also custom events, which means all micro frontends can listen to all events that are happening within a window space. When there are changes in the communication between micro frontends, that is, whether to communicate via local storage, session storage, or use state management, using store is a good option for data storage.
The configuration of the project itself is very simple. It can be implemented in different ways and this is one of them. It is a monorepo structure that contains both the host application and the remote.
In webpack.config.js we add remote to the host application. Here we are entering all remote modules, which is approachable by local module, it can be a string if there are more of them or object.
Shared – Enables sharing libraries which are needed for moving modules that are exposed. Every shared library can have a set of properties, some of them are eager – which if they are set to “true”, means that all shared modules can be compiled with exposed modules; Singleton: it is very significant and allows only one version of a shared module; strictVersion: allows webpack to refuse a shared module if its version is not valid.
Filename – Is a unique name for a bundle
Exposed – Path module or files which is exposed in a container, it can be an object or array