Using microfrontends to create robust interfaces for complex applications

Modern sites are no longer simple pages with text and pictures. They can simultaneously be an online store, an online calculator, a customer account manager with a personal set of services. Developers have to figure out how to combine different modules so that they do not interfere with each other and do not slow down the development of the product as a whole. One of the possible ways is microfrontends.

The term “microfrontends” appeared at the end of 2016 on the ThoughtWorks technology radar. This approach extends the concept of microservices to the world of interfaces.

Many web resources are a front-end monolith - a multifunctional single-page application that sits on top of a microservices architecture. Over time, the outer layer, often developed by a separate team, grows too large to maintain efficiently.

The microfrontend concept aim to view a website or web application as a collection of features owned by independent teams. One team develops online sales, another interacts with clients, the third integrates analytics. Everyone has their own area of ​​business in which she develops features from start to finish, from the database to the user interface.

They converge on an interface that allows all participants to develop services without interfering with each other.

How the technology works in practice

1. The simplest form - iframes. These can be easily assembled into a coherent whole, but present difficulties when transferring data to and from individual applications. In addition, if you need to optimize the site for search engines, iframes are no longer the way as the content from individual microfrontends will not be indexed for the overall page.

2. Web components. The frontend can implement custom elements, i.e. essentially wrapping a fragment of layout code, styles and scripts in an HTML tag. The disadvantage of this approach lays in the abundance of JavaScript code that slows down the browser responses.

There is also the matter of encapsulating styles using the Shadow DOM which is a separate topic itself. There are questions about the attributes of custom elements and properties as an object: often they do not match in type, require a separate description or logic for casting types to one.

3. A relatively new Webpack 5 feature is Module federation. Several applications are created, one is marked as a host, the rest declare the export of code to externals. Further, the host can pull up this data upon request to the “donor” application. Angular, which we work with, allows loading entire modules from a remote application. There are mechanisms for handling common dependencies - since microfrontends are separate bundles, the dependency code between them will be duplicated. The ability to work with them using the framework tools greatly simplifies the tasks of the team.

 

The last option seems to be the best one for us. In one of the new projects, we are now building this logic based on the Angular Module Federation. In this case, separate modules are marked external, which can then be loaded from the shell application as a lazyload. Angular Universal does a pretty good job of rendering on separate routes.

What we need:

  • Microfrontends in Angular
  • Shell application with described routing and loading of microfrontends in the form of lazyload modules
  • A back end using Angular Universal to pre-render on any requested page route.

As a result, we get a convenient and efficient interface within which its various modules are being developed. Business is less dependent on technological constraints, customers become happier - new features are quickly added to the site, the interface suffers less from failures.

To sum up: we recommend considering microfrontends if one needs to combine several frameworks within one interface or split a large project into many independent subprojects with separate teams.

Our latest publications

See our knowledgebase