In the previous articles, we introduced the concept of microfrontends and discussed their advantages and disadvantages. Now it's time to dive into the tools and technologies that can help bring a microfrontend architecture to life.
We will cover some of the popular frameworks and libraries available, and guide you through setting up a microfrontend architecture using Single-Spa.
Overview of Microfrontend Tools and Technologies
The adoption of microfrontends has led to the development of several tools and libraries that facilitate the implementation and integration of multiple frontend applications.
Below are some of the most commonly used tools.
Webpack Module Federation
Webpack Module Federation is a feature introduced in Webpack 5 that allows you to share code between different JavaScript applications at runtime. It simplifies the process of dynamically loading code from other applications, making it a powerful tool for microfrontend integration.
- Advantages: Module Federation enables seamless sharing of dependencies across microfrontends, reducing duplication and improving performance. It also allows for dynamic loading, meaning teams can independently update their parts of the application without a full rebuild.
- Disadvantages: One of the key challenges with Webpack Module Federation is the complexity of configuring the federation properly. Managing shared dependencies can lead to version mismatches and potential conflicts, especially when different microfrontends require different versions of the same library. Additionally, it requires deep knowledge of Webpack, which may have a steep learning curve for some developers.
Single-Spa
Single-Spa is a popular microfrontend framework that stands out due to its runtime integration capabilities and true framework-agnostic approach that allows you to combine multiple JavaScript frameworks in a single application. It serves as a "root config" that helps in managing how different microfrontends are loaded and interact with each other.
- Advantages: It provides a centralized "root config" to orchestrate how different microfrontends are loaded and interact with each other, giving developers granular control over the lifecycle of each microfrontend. Single-Spa also offers a comprehensive set of plugins, strong community support, and detailed documentation, making it an ideal choice for those getting started or working with diverse technologies.
- Disadvantages: The flexibility of combining multiple frameworks within a single application comes with added complexity. Single-Spa requires a good understanding of how each framework manages state and rendering, which can be a learning curve for teams that are not familiar with hybrid environments.
Vite Plugin Federation
Vite Plugin Federation extends Vite's functionality by enabling module federation, similar to Webpack's approach. This tool provides a modern alternative to traditional bundlers and focuses on faster build times.
- Advantages: With Vite's fast build times and the added benefit of module federation, this plugin is well-suited for those who prefer a modern, lightweight development experience.
- Disadvantages: Vite Plugin Federation is relatively new compared to Webpack, which means it may lack the stability and maturity that Webpack provides. It also has limited community support, which can make troubleshooting issues more difficult. Compatibility with other existing tools and frameworks may also be limited.
Open Components
Open Components is a library that focuses on server-side rendering (SSR) and dynamic delivery of components. It allows developers to create reusable components that can be independently published and consumed by different applications.
- Advantages: Ideal for server-side rendered applications where delivering small, reusable components is a key requirement. It helps in achieving dynamic rendering and faster time-to-interactive.
- Disadvantages: Open Components can introduce additional server-side complexity, as it requires setting up and maintaining a dedicated server for delivering components. It also lacks the flexibility to handle complex frontend requirements, making it more suitable for simpler use cases. The community around Open Components is not as active, which can limit access to support and resources.
Luigi
Luigi is an open-source microfrontend framework developed by SAP. It allows developers to create a consistent navigation experience while integrating different microfrontend components.
- Advantages: Luigi comes with built-in features like routing and authorization management, which makes it a strong choice for enterprise-grade applications.
- Disadvantages: Luigi is tightly coupled with its own set of tools and conventions, which can limit flexibility. This can be restrictive for teams that prefer more customization or need to integrate with different routing or authorization solutions. Additionally, the learning curve can be steep, especially for developers unfamiliar with Luigi's specific conventions.
Piral
Piral is a framework that enables you to create modular frontends using microfrontend architecture. It allows teams to independently develop and deploy different parts of an application while still delivering a cohesive user experience.
- Advantages: Piral offers an extensive set of plugins and customizable options, which makes it suitable for projects that require high flexibility and modularity.
- Disadvantages: The extensive customization options can make Piral challenging to configure, particularly for teams new to the framework. The complexity of setting up Piral's infrastructure can lead to longer development times. Additionally, managing versioning and updates for shared components across microfrontends may require significant effort.
Mosaic
Mosaic is another microfrontend framework developed to help large teams build cohesive frontend applications from smaller, self-contained components. It focuses on scalability and collaboration across multiple teams.
- Advantages: Mosaic emphasizes team collaboration and allows each microfrontend to be easily integrated with others, supporting scalability for larger projects.
- Disadvantages: Mosaic may introduce performance overhead due to the additional layers of abstraction involved in managing microfrontends. It also requires a steep learning curve, as it involves understanding Mosaic's specific integration and deployment workflows. The community around Mosaic is smaller compared to more established tools, which can make finding support more challenging.
Why We Choose Single-Spa
After evaluating all the options mentioned, we chose Single-Spa as our primary tool for implementing microfrontends. Here are some of the reasons behind our decision:
- Comprehensive Documentation: Single-Spa has well-structured, easy-to-follow documentation that helps guide teams through the entire microfrontend lifecycle—from setup to deployment. This makes it easier for teams to onboard and begin implementing microfrontends without unnecessary delays.
- Active Community: The framework's active community ensures that there are frequent updates, improvements, and a wide range of available plugins and integrations. This community support reduces the risk of being stuck on issues and provides a wealth of resources for troubleshooting and best practices.
- Runtime Integration and Framework-Agnostic Approach: Unlike other tools that are often framework-agnostic only at build-time, Single-Spa offers true runtime integration of multiple frameworks. It allows developers to mix and match different frontend technologies (e.g., React, Angular, Vue) within the same application, all managed at runtime. This flexibility makes Single-Spa uniquely capable of allowing different teams to work autonomously on different parts of the application without needing to align around a single stack or technology. This is especially valuable when migrating legacy codebases or when different teams prefer different frameworks.
- Unified Orchestration and Lifecycle Management: Single-Spa provides a centralized "root config" that acts as the entry point for all microfrontends. It offers detailed lifecycle management for each microfrontend, including mounting, unmounting, and updating, allowing developers to have granular control over each part of the application. This level of control is key for optimizing performance, memory usage, and overall application behavior.
- Versatile Use Cases: Single-Spa supports a wide range of use cases, including server-side rendering, lazy loading, and seamless communication between microfrontends. This makes it a comprehensive solution for complex applications that require flexibility and scalability. Its versatility allows teams to address different architectural needs, such as integrating legacy systems or gradually adopting microfrontends.
- Testing and Debugging Capabilities: The robust testing and debugging tools provided by Single-Spa help developers quickly identify and resolve issues across different microfrontends. The framework supports tools that allow for isolated testing of individual microfrontends, which is crucial for maintaining stability in a complex multi-framework environment.
In summary, Single-Spa’s unique ability to handle multiple frameworks at runtime, its robust lifecycle management, and its flexibility in allowing different technologies to coexist made it the ideal choice for our microfrontend implementation.
It allows us to effectively manage complexity, support team autonomy, and maintain a consistent user experience across the entire application.
Step-by-Step Guide to Setting Up Microfrontends with Single-Spa
To help you get started with microfrontends, let's go through the basic steps involved in setting up a microfrontend architecture using Single-Spa.
These steps are up to date with the Single-Spa documentation at the time of writing, we recommend checking the official documentation for updates.
Create the Root Config Application
The root config is the container application that serves as the entry point for your microfrontends. It handles the loading and orchestration of all the microfrontends that will be part of your application.
Use the Single-Spa CLI to generate the root config application:
npx create-single-spa --module-type root-config
This will scaffold a basic root config that can be customized to meet your specific needs.
Set Up Microfrontend Applications
Create individual microfrontends for different parts of your application. For example, you could create a Navigation microfrontend using React, a Products microfrontend using Vue, and a Checkout microfrontend using Angular (Spoiler alert: this is what we're going to do in the next articles).
Use the Single-Spa CLI to create each of them:
npx create-single-spa --module-type app-parcel
Each microfrontend can be developed and deployed independently.
Configure Import Maps
The import map is a crucial part of Single-Spa's architecture. It defines where each microfrontend is located, allowing the root config to dynamically load and execute them.
Import maps can be used to register the URLs for each microfrontend, making it easy to update and version different components without modifying the root config.
You can find this file in the root-config project:
src/importmap.json
Routing and Navigation
Set up routing in the root config to determine when and how each microfrontend should be loaded. Single-Spa uses path-based routing, allowing each microfrontend to be mounted based on specific URL paths.
Routing can be configured to ensure a seamless transition between microfrontends, giving users the experience of a single, unified application.
To start with this, again in the root-config project, you can take a look at:
src/microfrontend-layout.html
Shared Dependencies
Sharing dependencies between microfrontends can help reduce duplication and improve performance. Single-Spa allows you to share common libraries like React or Vue across microfrontends, ensuring that each microfrontend doesn’t need to load its own instance.
In the root-config project, you can manage shared dependencies by adding them to the importmap.json file. For example:
{
"imports": {
"react": "https://cdn.jsdelivr.net/npm/react@17.0.2/umd/react.production.min.js",
"react-dom": "https://cdn.jsdelivr.net/npm/react-dom@17.0.2/umd/react-dom.production.min.js"
}
}
By using shared versions, you can ensure consistent behavior across all microfrontends and improve load performance by reducing duplication.
Communication Between Microfrontends
Communication between microfrontends can be achieved using RxJS or similar tools. This allows microfrontends to share data or trigger events without direct coupling.
To implement this, you can create a Utility Module that uses RxJS to facilitate communication.
Use the Single-Spa CLI to create it:
npx create-single-spa --module-type util-module
Inside of that project, for example, you could create a module named counter-module.ts
import { BehaviorSubject } from "rxjs";
// Initialize the shared count state with an initial value
const countSubject = new BehaviorSubject<number>(0);
// Expose an observable to subscribe to the count changes
export const count$ = countSubject.asObservable();
// Define getter and setter functions for the count
const getCartCount = (): number => {
return countSubject.getValue();
};
export const setCartCount = (): void => {
countSubject.next(getCartCount() + 1);
};
This utility module can be imported by different microfrontends, allowing them to communicate through events without being tightly coupled.
Conclusion
There are several tools and technologies available for implementing microfrontends, each with its own advantages and use cases.
In this article, we explored popular tools like Webpack Module Federation, Single-Spa, Vite Plugin Federation, and more. We also provided a step-by-step guide to setting up microfrontends using Single-Spa, a framework that offers flexibility, scalability, and ease of use.
In the next article, we will dive into the specifics of each microfrontend project, exploring how to implement different technologies within a cohesive microfrontend architecture.
Top comments (1)
Hey everyone! 👋 If you're enjoying this series, check out the GitHub repositories I created to complement these articles:
github.com/joacod/microfrontends-r...
In the README, you'll find links to all the other microfrontend repositories.
Dive in, explore how everything connects, and see the code in action! 🚀