Summary of the Article
Have a project in mind?Schedule a Call
Building Micro Frontends with React: A Scalable and Flexible Architecture for Web Applications
Reading Time: 6 minutes
Summary of the Article
In the world of web development, developing large-scale applications can be very challenging. The more complex the applications become, the more difficult it can be to maintain code consistency and scalability. MicroFrontends aims to solve this problem by breaking web applications into smaller, more manageable pieces.
In this blog, we will explore the benefits of using micro-frontends and how to create them with React.
What is Microfrontends?
Microfrontends is a software architecture pattern that applies the principles of microservices to front-end development. It breaks down a large, complex user interface into smaller, independent, and reusable modules, each with its own functionality and development team.
The philosophy behind micro-frontends is to view the web application as a composition of functions that are in the hands of different independent teams.
By using micro-frontends, companies can create and maintain large-scale web applications with greater flexibility and speed. This approach enables better scalability, greater development efficiency, and shorter time-to-market.
But first, let us look at what challenges monolithic architecture brings:
In the monolithic architecture, the web browser communicates with the front-end monolith, which in turn communicates with the back-end API services that interact with the database. All components are tightly coupled and interact directly with each other. Any change to one part of the front-end monolithic application can affect other parts of the application, and scaling the application can be challenging.
In micro front-end architecture, on the other hand, the web browser communicates with the micro front-end shell, which is responsible for loading and managing the various micro front-ends (in this example, MF -A, MF -B, and MF -C). Each micro-frontend is a self-contained module that can be developed, tested, and deployed independently.
The monolithic architecture can become a bottleneck when the application is scaled up, and changes to one component can affect the entire system.
Steps to approach the micro-frontend architecture
Identify different parts of the front-end application that can be divided into smaller, independent parts.
Deciding on a common framework and language for developing micro frontends.
Implement a shell application or orchestrator to load and manage micro frontends.
Decide on a strategy to bundle and deploy micro frontends.
Implement a testing strategy that ensures that each micro-frontend can be tested both in isolation and as part of the larger application.
To effectively load and manage different micro-frontends in a micro-frontend architecture, a frontend orchestrator is needed. This orchestrator is responsible for loading and managing the different micro-frontends and facilitating communication between them.
When two applications share a common composite module, the consuming application dynamically loads the module at runtime. If the consuming application does not have a required dependency for the composite module, Webpack downloads the missing dependency from the source of the composite module. This means that the consuming application can seamlessly use the composite module without having to worry about manually installing dependencies.
In addition, Module Federation allows developers to create highly modular applications that can be assembled from smaller, independent parts. This can lead to faster development cycles, more efficient use of resources, and easier maintenance of complex applications.
One of the key benefits of Module Federation is the ability to facilitate collaboration between different teams and organizations. By allowing different applications to share code and dependencies, teams can collaborate more effectively, share resources and knowledge, and develop better applications faster.
The diagram pasted below shows a micro-frontend architecture where there are two microfrontends:
MF1 running on port 3000
MF2 runs on port 3001
Module Federate Implementation
Using module federation, MF1 exports two components (components A and B) that can be dynamically imported by MF2. This allows MF2 to use MF1’s components without having to include them in its code base. MF2 has only one component, component X.
To federate components from the Webpack configuration, you can use the Federation Plugin module in your Webpack configuration.
Example of how to federate a component
First, you need to specify which components to enable for federation in the Microfrontend Checkout Webpack configuration. Here is an example of how to enable a React component:
In this example, we represent the Button component from ./src/components/Button in the first micro-frontend codebase (named Checkout). The name property specifies the name of the microfrontend, while the exposes property specifies which components to make available to the composite.
Next, in the Webpack configuration of the second micro-frontend (named Listing), you need to specify which components to federate. Here is an example of how to include the Button component from Checkout:
In this example, we add the Button component of Microfrontend Checkout. The remotes property specifies which micro-frontend to connect from and which remote input file to load.
Once you have configured the webpack configurations, you can import the federated component into your Microfrontend 2 codebase and use it as follows:
In this example, we import the Button component from Microfrontend 1 and use it in the App component in the Microfrontend 2 codebase. Note that we use the Checkout/Button syntax to specify the location of the federated component.
Advantages of micro-frontend architecture
Improved scalability: It enables better scalability by dividing a large front-end application into smaller, self-contained modules that can be developed and deployed independently.
Increased flexibility: The micro-frontend architecture provides more flexibility, as different teams can work on different parts of the frontend application without getting involved in each other’s work.
Enhanced maintainability: It enables better maintainability through more efficient updates and upgrades. Each microfrontend can be updated or upgraded independently without affecting other parts of the application.
Faster development cycles: The microfrontend architecture enables faster development cycles, as different teams can work in parallel on different parts of the application.
Improved performance: This can help improve performance by allowing lazy loading of components, reducing the amount of code that needs to be loaded in advance.
Better separation of concerns: It allows for better separation of concerns by dividing the front-end application into smaller, self-contained modules that can be developed and tested independently.
Drawbacks of micro-frontend architecture
Increased complexity: This can increase the complexity of the overall frontend application by requiring additional infrastructure, tools, and processes to manage the individual micro-frontends and their interactions.
Increased communication overhead: With this architecture, communication between different teams responsible for different micro-frontends can be more challenging, as there may be additional coordination and communication needs.
Additional testing requirements: The architecture of the micro-frontends requires additional testing effort to ensure that the individual micro-frontends work together seamlessly and do not introduce new bugs or problems.
Inconsistencies and conflicts in micro-frontends of different teams: Potential inconsistencies and conflicts in coding standards, design patterns, and other implementation details between micro-frontends developed by different teams.
So to conclude, Microfrontends can improve development agility and enable independent teams to work on specific parts of a complex web application. They offer flexibility in choosing technology and can aid scalability. However, managing multiple front-end applications can add complexity, and ensuring consistency across parts can be a challenge.