Micro-Frontends: The Future of Modern Web Development

Margarita Syddall
Flux IT Thoughts

--

Let us start with the basics. The concept of “micro-frontend” refers to a vertical architecture. The system is based on small and reusable modules, independent of each other, which make up a single app.

Explanatory diagram:

Three independent modules that together constitute an ecommerce platform. One contains the development of the header and footer, another one the development of the cart, and the third one contains the development of the home page. The latter consumes the header and footer on one side and the cart on the other.

A Bit of History

Taking a brief look back at the history of architectural systems, we know that, previously, apps used to be developed as monoliths and both back and front end were part of the same block. Needless to say, the disadvantages (risks, development difficulties, and conflicts to resolve in each merge) were evident.

Later on, back and front end were separated into two independent blocks, which, despite making development more flexible, ultimately brought along the same disadvantages.

Between 2012 and 2014, the concept of microservices was introduced in the back end. The back end is now an app composed of several services that can be deployed independently.

Furthermore, in the front end, the concept of Self-Contained Systems emerged. This architectural model focuses on the independent development and implementation of individual parts, which communicate with each other through links, and it follows a vertical architecture model.

Consequently, the concept of micro-frontends first emerged in 2016, and it has been gaining popularity ever since as a scalable approach to project development.

Today, the architecture of well-known apps such as Spotify, Netflix, Amazon, Airbnb, among others, is based on MFs.

Benefits

  • Quick and accessible implementation: Since they are independent apps with specific responsibilities, less time is needed for pipelines and deployment. This results in a better experience for Developers and reduces the risk of errors.
  • Minimization of failures and blocking tasks: Module failures and blocks do not affect other modules.
  • Testing simplification: Since they are apps with unique responsibilities and defined boundaries, testing functions and components is easier.
  • Memory optimization: Each micro-frontend only includes its own necessary libraries and tools, thus optimizing memory usage. Since the browser only loads the necessary modules, this results in faster performance compared to loading the entire app.
  • Specialized teams: Because the system is made up of several independent apps, there is a chance of putting together autonomous teams specialized for each module, thus enhancing team members’ skills.

While I cannot identify specific disadvantages of using micro-frontends, it is worth noting that it cannot be used in every case and that there are several aspects to consider to successfully implement this model:

  • Single responsibility principle: To divide our project into several independent apps, we must precisely define the function and responsibility of each one to ensure a smooth communication flow between these apps.
  • Design guidelines: Since this model can be implemented in large teams and in teams with future prospects, it is important for the entire team to be aware of the expectations regarding the project’s design and style to avoid differences between the modules that may generate a poor user experience.
  • Independent states: It is imperative to avoid sharing states between apps, as this would make them no longer independent of one another.

Implementing Micro-frontends

There are several ways to implement MFs when developing. Tools such as Single-Spa, Module Federation, and SystemJS are the preferred choice.

In this article, we will be doing so with Webpack5’s ModuleFederationPlugin.

On the one hand, there is a command that solves all configuration issues and leaves the code ready for us to start developing and connecting apps.

npx create-mf-app

Very similar to the result we get from CRA (create-react-app), this command creates a file called webpack.config.js where all the magic takes place. This file has all the necessary configurations to build our app and use the necessary files, such as styles, images, etc. It has a key called plugins which has an array of several webpack plugins. One of them is ModuleFederationPlugin which contains:

  • name: Corresponds to the name we will give to the app we are working on.
  • filename: Corresponds to the file that will be created with all the necessary information for other apps to use. By convention, its value will be ‘remoteEntry.js’.
  • remotes: An object containing information about remote apps, i.e., those consumed by the app in question. Each consumed app will have a name (the same as the one designated in its own webpack.config) and a URL.
  • exposes: Contains the components to be shared with other apps.
  • shared: Contains the dependencies to be shared between apps so that the browser does not load them more than once.
webpack.config.js example

Host app webpack configuration file:

Remote app webpack configuration file:

Migrating an App from CRA to MF

If you want to migrate an app created with CRA to MF, there are several obstacles, but it is not impossible!

The first thing we need to know is that CRA has several dependencies and configurations that are behind the code we can see, and we will not be able to find them in our package.json, therefore, we will not be able to easily edit them, much less install new versions.

One of these dependencies is webpack version 3.

Since ModuleFederationPlugin is available from version 5 onwards, we must step away from default configurations of our CRA with the npm run eject command. This command brings us the dependencies, thus allowing us to edit or remove them, but at the same time, it breaks down their configurations, so it will depend on us to develop these configurations so that our app works again.

It is worth mentioning that this command is definitive, and once it is run, we cannot go back.

Once this is done, we will follow the same steps to connect our app with others through Module Federation.

Conclusion

The most important aspect to consider when approaching a project with micro-frontends is that, far from being a magic solution, it will be one challenge after the other. This architecture is still being worked on, and there is no single recipe for achieving the best result.

But, if we are developing an app with a certain complexity or looking for an architecture that allows us to obtain an efficient and autonomous development flow, micro-frontends are the ideal option to achieve scalable and performant code.

Acknowledgments

This article is written with the collaboration of my fluxer leader Leonardo Galdames, Technical Leader at Flux IT. Enjoy the reading!

Know more about Flux IT: Website · Instagram · LinkedIn · Twitter · Dribbble · Breezy

--

--

Margarita Syddall
Flux IT Thoughts

Front-end developer building cool stuff with React. Also a total aerial acrobat and nature enthusiast. 🌎✨ Living in Buenos Aires. Don't forget to clap!