Application Shell for React Micro Frontends

Sedang Trending 2 bulan yang lalu

Mastering Micro Frontend Integration: Achieving Cohesive UX and Optimized Performance.

Eden Ella

Bits and Pieces

An exertion ammunition is nan “container” that integrates micro frontends together. It provides nan layout, navigation, world state, and different communal elements shared crossed nan MFEs.

An app ammunition sets nan rules for connection betwixt nan micro frontends and betwixt nan micro frontends and nan shell. These rules and conventions guarantee a cohesive personification acquisition and optimized performance. They are besides tremendously adjuvant for nan improvement teams, arsenic they supply a clear and accordant measurement to build and merge these independent parts.

In this article, we’ll research really to build a strategy of a ammunition app, micro frontends, and shared components utilizing Bit’s Harmony platform. Every portion successful this strategy will beryllium built arsenic a Bit component that is independently developed, versioned, and delivered.

Let’s commencement by creating a workspace pinch a fewer of nan basal Bit components:

bit caller harmony my-project - env bitdev.symphony/envs/symphony-env --default-scope my-org.my-projectcd my-project

Run nan exertion locally to trial it retired for yourself:

bit tally my-project

Run nan UI to research nan Bit components maintained successful your workspace:

bit start

Your workspace should see nan pursuing components:

Our workspace contains components of various types. To understand really they activity together, let’s spell complete each one, starting pinch nan introduction constituent of our application, nan app ammunition aliases nan “platform”.

Our app shell, my-projectuses nan Harmony Platform to constitute respective independent pieces that supply full-stack functionality.

Unlike astir modular MFE integrations, this attack allows you to merge full-stack services arsenic good arsenic “frontend-only services”.

/** @filename: my-project.bit-app.ts */

import { HarmonyPlatform } from '@bitdev/harmony.harmony-platform';
import { NodeJSRuntime } from '@bitdev/harmony.runtimes.nodejs-runtime';
import { BrowserRuntime } from '@bitdev/harmony.runtimes.browser-runtime';
import { SymphonyPlatformAspect } from '@bitdev/symphony.symphony-platform';
import { HeaderAspect } from '@bitdev/symphony.aspects.header';
import { PeopleAspect } from '@my-org/people.people';
import { MyProjectPlatformAspect } from '@my-org/my-project.my-project-platform';

export const MyProject = HarmonyPlatform.from({
name: 'my-project',

/**
* nan infrastructure that integrates nan frontends/full-stack services
* among different things, it provides a measurement to registry caller routes
*/
platform: [SymphonyPlatformAspect],

/**
* nan imaginable runtimes for this system's services.
*/
runtimes: [new BrowserRuntime(bundleConfig), caller NodeJSRuntime()],

/** nan frontends/e2e-services that are loaded by this app ammunition */
aspects: [HeaderAspect, PeopleAspect, MyProjectPlatformAspect],
});

export default MyProject;

Head complete to nan symphony level scope, to study much astir it

The frontends aliases “services” integrated into nan level are defined arsenic aspects. This is simply a cardinal conception successful nan Harmony platform, which allows you to specify and merge full-stack services successful a elemental and accordant way.

Each work aliases “aspect” successful this strategy provides cross-cutting functionality. For example, my-project-platformallows different aspects to widen nan homepage pinch their sections aliases panels, headerallows different aspects to adhd items to nan app’s header and peopleprovides nan organization’s group guidance functionality.

Each facet exposes integration slots that different aspects tin usage to devour its services.

For example, nan panelsslot is defined arsenic follows:

/** @filename: my-project-platform.browser.runtime.tsx */

export people MyProjectPlatformBrowser {
constructor(
backstage panelSlot: PanelSlot
) {}

registerPanel(panels: Panel[]) {
this.panelSlot.register(panels);
return this;
}
fixed async provider(
// ...
[panelSlot]: [PanelSlot]
) {
// ...
}

export default MyProjectPlatformBrowser;

The peopleaspect uses this slot to registry its panel:

/** @filename: people.browser.runtime.tsx */

// imports...
import {
MyProjectPlatformAspect,
MyProjectPlatformBrowser,
} from '@my-org/my-project.my-project-platform';

export people PeopleBrowser {
constructor(...) {}

/**
* each facet lists its dependencies, which are different aspects it depends on.
*/
fixed limitations = [
MyProjectPlatformAspect,
];

/**
* The supplier method is nan introduction constituent for nan aspect.
* It receives nan limitations (other aspects) it needs
*/
fixed async provider(
[myProjectPlatform]: [ MyProjectPlatformBrowser ]
) {
piedPlatform.registerPanel([
{
category: 'People',
component: () => {
return <NewPeople />;
},
},
]);

return caller PeopleBrowser(config, menuItemSlot);
}
}

export default PeopleBrowser;

Developing and Testing your Micro Frontend successful its Full Context (while staying decoupled and independent)

Import nan app ammunition (Bit component) from its distant scope into your section workspace to trial your micro frontends and services successful nan discourse of nan full application.

This will supply you pinch an fantabulous dev acquisition akin to moving connected elemental monolithic apps. More importantly, it will let you to tally end-to-end tests to verify your MFE is moving arsenic expected earlier its release.

So far, we’ve seen really nan level integrates aspects, which are fundamentally full-stack services. However, arsenic mentioned earlier, our full strategy is composed of Bit components that are independently developed and released.

This includes shared components of smaller granularity, specified arsenic UI components, hooks, utilities, and more.

For example, nan peopleaspect is composed of respective Bit components, including nan people-lobby(UI) component, nan use-user-listhook that fetches a database of users and moreover nan userentity component, which is utilized to specify nan personification model.

Unlike nan aspects, which are much loosely coupled and supply cross-cutting functionality, these components are much tightly coupled and supply circumstantial functionality. They are integrated aliases composed together arsenic regular dependencies:

/** @filename: people.browser.runtime.tsx */

/** a spot constituent consumed arsenic a regular dependency */
import { PeopleLobby } from '@my-org/people.ui.people-lobby';

These components tin beryllium utilized to stock codification betwixt nan decoupled parts of nan strategy (micro frontends, microservices, aliases full-stack service) for faster development, amended consistency, and easier maintenance.

The ‘people’ facet dependencies

Run spot templates to database nan disposable Bit constituent templates. Choose ‘aspect’ to create a micro frontend aliases full-stack work (as an aspect). For example:

bit create facet my-header

This attack to micro frontend integration tin only beryllium utilized successful build-time. What astir runtime MFE integration?

The Harmony level is designed to activity pinch build-time integration of MFEs, which has go a celebrated approach, particularly since nan preamble of Bit components.

A build-time integration of Bit components is simply a powerful measurement to guarantee that nan MFEs are integrated successful a accordant measurement and that they are optimized for capacity and personification experience.

All this tin beryllium achieved without compromising nan MFEs' independency (or that of nan teams that support them), which tin beryllium developed, versioned, and delivered independently (as Bit components).

Having said that, Bit components tin besides beryllium deployed and integrated astatine runtime. This is simply a different attack that will beryllium covered successful early articles (stay tuned).

It’s besides worthy noting that definite elements tin beryllium integrated into nan level astatine runtime. For example, nan pursuing facet will usage nan (aforementioned) MyProjectPlatformAspect and SymphonyPlatformAspectto widen nan app. Here, nan MFE is injected successful build-time but loaded successful runtime.

// imports...

/** load an MFE successful runtime (in this case, an ES Module) */
export usability PanelMfe() {
const HelloPanel = lazy(() =>
import('https://esm.sh/@learn-bit/hello-card@0.0.2').then((module) => ({
default: module.HelloCard,
}))
);

return (
<Suspense fallback={<p>Loading...</p>}>
<HelloCard />
</Suspense>
);
}

export people MyAspect {

fixed async provider(
[myProjectPlatform, symphonyPlatform]:
[MyProjectPlatformBrowser, SymphonyPlatformBrowser]
) {
/** inject nan MFE arsenic a "panel" successful nan homepage */
myProjectPlatform.registerPanel([
{
component: () => {
return <PanelMfe />;
},
},
/** inject nan MFE to nan app navigation (add a route: 'my-domain/hello) */
symphonyPlatform.registerRoute([
{
path: 'hello',
component: () => {
return <PanelMfe />;
},
},
]);
]);
}

How do I deploy nan app ammunition and nan micro frontends?

The app ammunition (“my-project”) is simply a Bit app component, which tin beryllium deployed to immoderate level utilizing a deployment usability that runs whenever a caller type is released.

For example:

/** @filename: my-project.bit-app.ts */
export const MyProject = HarmonyPlatform.from({
name: 'my-project',
// …
deploy: myDeployFunction()
});

export default MyProject;

How does nan level guarantee that nan aspects are integrated successful nan correct order?

The harmony level calculates nan aspect’s dependency chart to guarantee that aspects are integrated successful nan correct order.