Building a Host Application for Your Micro Frontends



This content originally appeared on Bits and Pieces – Medium and was authored by Eden Ella

Creating a shell application that meets all non-functional requirements

What is a ‘shell application’?

A shell application, often called a “container” or “host,” is the central piece that combines various micro frontends. It provides the overarching structure and standard functionality that each micro frontend can utilize. Think of it as the scaffolding that supports and connects the individual pieces of your web application.

The functional requirements of a shell application include routing and navigation, shared state management, loading and orchestrating Micro Frontends, and providing shared services and utilities (such as logging, analytics, etc.).

Non-functional requirements of a shell application

Non-functional requirements (NFRs) are critical for the success and usability of a shell application in a micro frontend architecture. They define the quality attributes, performance, and constraints that the shell app must meet. These qualities include load time, responsiveness, extensibility, security, etc.

From a siloed monolith to a transparent and composable system

The key to “checking all the NFR boxes” is sharing well-documented components across independent teams and projects.

When implemented as a siloed monolith, a ‘shell app’ cannot provide the services its micro frontends need. Instead, the shell app team should provide the building blocks for MFEs, the SDKs and types for various integrations, and even the host application context for proper development and testing of independent MFEs.

To build our composable system out of shareable, independent componetns, we’ll use Bit.

Bit. Composable software platform.

Visit this deployed solution, Bit organization, and GitHub organization to explore the full solution used here as a demo.

The complete demo (visit the deployed app, Bit org and Github org)

To read about the complete solution, head over to this blog post:

Micro Frontends: A Practical Step-by-Step Guide

Sharing type components for better extensibility and usability

Bit is often used to share “entity components” between a service provider and its clients. An entity component provides the types to describe and validate the data being transferred (from the service to the client and vice-versa) as well as the utilities needed to handle and manipulate that data.

The same methodology can be used to describe the types of data entities that a micro frontend can implement to integrate into the shell application.

For example, our host application allows micro frontends to register a menu in the top navigation bar.

Our deployed solution: https://bit-bazaar.netlify.app/

The host app team created an interface for other teams to implement if they wish to use this type of integration.

For example:

export interface NavItem {
label: string;
path: string;
icon?: string;
children?: NavItem[];
}

The type would then be shared as a Bit component to make it available across projects, maintained in separate repositories (the various Micro frontends):

The ‘navigation’ Bit component

In this example, the interface is implemented by the “Storefront” and “Blog” MFEs:

The ‘navigation’ type graph of dependent components

For example:

Navigation implemented and exposed by the ‘blog’ micro frontend

Sharing UI components for consistency, performance, and faster dev

Sharing UI components is nothing new. The trick is to do it in a way that does not create a compromise between development and user experience.

Building a UI Library for Your Micro Frontends and Apps

UI components should be shared as independent pieces with individual versioning. This allows MFE teams to pick and choose the componetns they need and gradually upgrade their component versions (while avoiding meaningless updates to their project). This is contrary to how things are usually done when UI components are shared as “mega libraries.”

Mega libraries that include a single version for multiple components force the MFE teams into an “all or nothing” situation that often results in hidden workarounds (mainly creating things from scratch) that generate less optimized bundles and less consistency in UI/UX.

https://bit.cloud/bit-bazaar/design/~components?aggregation=none

Sharing context components for a better DevX and app robustness

The context components that comprise the app shell context can be shared and consumed by the MFEs for their development.

Shared context componetns

One way would be to wrap component tests and previews with the shared context componetns. For example:

/**
* @filename: app-bar.composition.tsx (the preview file for the app-bar)
*/

/**
* import the shared context to test/preview components in your MFE
*/
import { ThemeProvider } from '@bit-bazaar/design.theme.theme-provider'
import { AuthProvider } from '@bit-bazaar/shell-app.auth.auth-provider'
import { AppBar } from './app-bar'

export const AppBarPreview = () => (
<ThemeProvider>
<AuthProvider mock>
<AppBar />
</AuthProvider>
</ThemeProvider>
)

Immutable instances of the shell application

Another way sharing context can improve development is by sharing the entire app shell as an immutable package. This allows MFE teams to run their MFEs in the full context of the shell application while preventing any accidental changes to the shell app (maintained by a different team).

This is done with the help of a particular component, a ‘platform.’ These components are orchestrators of frontend and backend applications. They enable you to quickly run a complete system composed of multiple microservices and micro frontends. Some are maintained by you, while others are only consumed for dev purposes.

For instance, the ‘Storefront’ team can run the ‘Storefront’ MFE in its full context (shell app and even other MFEs) by running the MFE inside the context of the immutable shell application. The team uses a platform component that ensures they run their MFE and then the host app that consumes it.

The platform component used for development by the Storefront MFE team
bit run storefront-platform
The ‘Storefront’ MFE running inside the context of the shell application

Read this blog post about Module Federation with Bit to learn how to generate your own version of a ModFed platform component.

Micro Frontends: A Practical Step-by-Step Guide


Building a Host Application for Your Micro Frontends was originally published in Bits and Pieces on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Bits and Pieces – Medium and was authored by Eden Ella