Eines unserer Hauptziele bei FloQast ist es, Hochleistungsteams zu unterstützen. In diesem Artikel wird eine Methode beschrieben, mit der wir unsere Geschwindigkeit und Effizienz steigern, indem wir eine Micro-Frontend-Architektur mit React implementieren.
Aktualisieren: Seit der Veröffentlichung dieses Artikels sind wir auf eine neue Micro-Frontend-Architektur umgestiegen. Die unten beschriebenen Konzepte sind immer noch sehr relevant und lesenswert; wir haben lediglich die Implementierung geändert. Auschecken Wie FloQast unsere Micro-Frontend-Architektur skaliert um zu verstehen warum!
Demontage des Frontend-Monolithen
Inzwischen ist das Konzept von Mikrodienste ist in der Softwarebranche allgegenwärtig geworden und verwendet lose gekoppelte Dienste anstelle eines einzigen Backend-Monolithen. Zu den Vorteilen einer serviceorientierten Architektur gehören:
- Eingrenzung des Umfangs der einzelnen Services, wodurch wiederum der Teamaufwand reduziert wird
- Schaffung einzigartiger Bereitstellungspipelines, was wiederum zu einer Reduzierung führt Vorlaufzeit (die Zeit, die zum Erstellen, Testen und Bereitstellen von Code benötigt wird)
Microservices haben zwar dazu beigetragen, den Backend-Monolithen abzubauen, aber wir haben immer noch ein großes Mono-Frontend. Dies führt nicht nur zu einer Überschneidung der Verantwortlichkeiten zwischen den Teams, sondern die gemeinsame Codebasis bedeutet auch eine gemeinsame Bereitstellungspipeline, was sich anfühlt, als würde man eine Autobahn zu einer einzigen Spur zusammenführen.

Indem wir den Leitprinzipien von Microservices folgen und die Belange des Mono-Frontends in separate Clients, auch Micro-Frontends genannt, aufteilen, können wir daran arbeiten, dieselben Vorteile im Frontend zu erzielen.
Jeder Kunde befindet sich in seinem eigenen Repository und verfügt über seine eigene Bereitstellungspipeline, was schnellere Durchlaufzeiten ermöglicht und den Aufwand für jedes Team reduziert. Ein zentraler Hub setzt dann zur Laufzeit alle Clients zusammen und vermittelt so die Illusion einer einzigen Anwendung. Endergebnis: Eine einheitliche Benutzererfahrung mit einer entkoppelten Entwicklererfahrung.

Quelle: Mikro-Frontends
Micro-Frontends mit React erstellen
Jeder Client ist eine komplette React-Anwendung, die mit React-App erstellen. All dies ist in einer einzigen Datei index.html zusammengefasst, die vom Hub bereitgestellt wird. Der Hub verwaltet auch das Root-Level-Routing, um zu bestimmen, welcher Client geladen werden soll.

Ein Benutzer besucht floqast.app, das den Client-Hub lädt; dann lädt der Hub je nach URL-Pfad den entsprechenden Client.
Einige Änderungen am Bundle, produziert von Webpack sind notwendig, um die Clients von eigenständigen Anwendungen in zusammensetzbare Anwendungen umzuwandeln:
- Ein einzelnes Paket anstelle von Chunks ausgeben — Auf diese Weise kann der Hub das Paket des Kunden einfach abrufen.
- Ein Fenstermodul ausgeben — Dadurch kann der Hub das Paket des Clients dynamisch laden.
- Exportieren, nicht rendern — Delegieren Sie das Rendern vom Client an den Hub.
Wir verwenden Craco um die zugrunde liegenden Konfigurationen zu überschreiben, ohne auswerfen. Durch Ersetzen React-Skripte mit Craco, jedes Skript lädt zuerst alle Konfigurationsüberschreibungen, die in definiert sind craco.config.js.
Hier sind Arbeitsmodelle von zwei Clients: einem Dashboard-Client und einem Admin-Einstellungsclient.
Der Hub ist auch eine React-Anwendung und verwendet React-Router, erstellt für jeden Client eine neue Route. Das Mikroclient Die Komponente ist dafür verantwortlich, das Paket des angegebenen Clients dynamisch in das DOM zu laden, indem reaktionsladbar Bibliothek.
Und hier ist ein funktionierendes Modell des Hubs. Es lädt dynamisch die beiden oben gezeigten Clients.
Mögliche Hindernisse und wie wir sie überwinden
Die entkoppelte Natur einer Micro-Frontend-Architektur trägt zwar dazu bei, das Entwicklererlebnis zu verbessern, aber wir wollen unsere Endbenutzer nicht aus den Augen verlieren. Das Aussehen und Verhalten der App sollten konsistent bleiben, unabhängig davon, welchen Bereich der App der Benutzer besucht. Es spielt keine Rolle, wie schnell wir Code versenden können, wenn das Endergebnis kein Vergnügen ist.
App-übergreifende Kommunikation
Um allen Kunden ein nahtloses Erlebnis zu bieten, sollten sie in der Lage sein, eine bestimmte Ebene des Benutzeroberflächenstatus zu teilen. Sie sollten jedoch so lose wie möglich miteinander verbunden bleiben, damit wir nicht wieder zu einem Monolithen zurückkehren und die Vorteile verlieren, die wir uns erhoffen. Daher sollte jede Kommunikation zwischen ihnen indirekt und asynchron abgewickelt werden. Einige Beispiele sind:
- Persistent im gemeinsam genutzten Speicher - Ein Client schreibt in den Speicher, sodass andere dann daraus lesen können. Dies kann je nach Lebensdauer der Nachricht ein Webspeicher oder ein Backend-Speicher sein.
- Ausgeben benutzerdefinierter Ereignisse - Ein Kunde sendet ein Ereignis aus, das es anderen ermöglicht, zuzuhören und entsprechend zu reagieren.
Ein Beispielszenario mit benutzerdefinierten Ereignissen
Ein Benutzer besucht die Admin-Einstellungen (Einstellungen-Client), wechselt das aktive Unternehmen und navigiert dann zurück zum Dashboard (Dashboard-Client) in der Erwartung, dass das aktive Unternehmen zwischen den Seitenübergängen bestehen bleibt.
In diesem Szenario, wenn das aktive Unternehmen geändert wird, Einstellungen-Client gibt ein Ereignis namens „ActiveCompanyChange“ zusammen mit der ID des neu ausgewählten Unternehmens aus:
window.dispatchEvent(
new CustomEvent('activeCompanyChange', {
detail: { companyId: nextCompanyId },
})
)
Das Dashboard-Client hört dann auf dieses Ereignis und ergreift Maßnahmen:
window.addEventListener(
'activeCompanyChange',
evt => setActiveCompany(evt.detail.companyId)
)
// Be sure to remove any added event listeners to prevent memory leaks.
Geteilte Styles
Der Hub bietet nicht nur das Top-Level-Routing, sondern auch das gemeinsame Layout. Dadurch wird sichergestellt, dass jeder Client dieselbe umgebende Schnittstelle nutzt. Alle Änderungen am Layout werden sofort in jedem übernommen, ohne dass spezielle Maßnahmen erforderlich sind.
Wir pflegen auch eine UI-Bibliothek, aus der Kunden gemeinsame Komponenten importieren können. Informationen zu den Herausforderungen, vor denen wir bei der Verwaltung aller CSS-Elemente stehen, die unsere Komponenten stylen, finden Sie unter Gestylte Komponenten in React: Abkehr von SCSS.
Gemeinsam genutzte Dienstprogramme
Wir sind auch auf das Problem gestoßen, gemeinsame Utility-Funktionen auf allen Kunden zu duplizieren. Bis zu einem gewissen Grad haben wir dies als akzeptablen Ansatz erachtet, hauptsächlich um schnell zu iterieren, aber auch um sicherzustellen, dass wir eine Implementierung vermeiden die falsche Abstraktion. Ähnlich wie in unserer UI-Bibliothek arbeiten wir jedoch daran, eine Bibliothek mit gängigen Hilfsprogrammen zu erstellen. Flodash, irgendjemand?

Fragmentierung des Teams
Neben den technischen Herausforderungen gibt es auch geschäftliche Bedenken. Eine davon führt möglicherweise zu einer Fragmentierung der Arbeitsweise von Teams. Wir bekämpfen dies, indem wir eine offene Kommunikation zwischen den relevanten Teams fördern. Neben der Einrichtung spezieller Slack-Kanäle, in denen wir die Konversationen fokussieren können, besteht eine besonders effektive Strategie darin, Vertreter aus jedem Team zusammenzubringen und einen kollektiven Brain-Dump über den aktuellen Stand der Dinge auszutauschen. Wir ermutigen alle, jede Frage, jedes Problem und jedes Anliegen zu verwerfen. Dann arbeiten wir daran, die Informationen in einer verdaulichen Liste zu kodifizieren. Als Nächstes erstellen wir für jeden Gegenstand eine bestimmte Aktion und delegieren eine an jedes Team. Schließlich treffen wir uns nach einiger Zeit wieder, um die Ergebnisse zu besprechen. Bei Bedarf wiederholen.
Wo gehen wir von hier aus hin?
Bisher war die Implementierung einer Micro-Frontend-Architektur mit React hier bei FloQast ein Erfolg. Dies ist kein einzigartiges Unterfangen für uns, und deshalb werden wir weiter forschen, lernen und teilen, während wir daran arbeiten, unseren Ansatz kontinuierlich zu verbessern.
Zu den zusätzlichen Ressourcen, die Sie in Betracht ziehen sollten, gehören:
- Mikro-Frontends - Ein großartiger Einführungsartikel in die Konzepte von Micro-Frontends.
- Einzel-Spa - Ein Framework für die Entwicklung von sofort einsatzbereiten Mikrofrontends. Ihre empfohlenes Setup ist voller großartiger Informationen.