Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.
Styling und CSS
Cascading Style Sheets (CSS) ist eine Sprache, mit der die Präsentation eines Dokuments zentral festgelegt werden kann, anstatt die Formatierung von Text und Objekten fest zu codieren. Die Cascading Funktion der Sprache wurde entwickelt, um mithilfe von Vererbung Prioritäten zwischen Stilen zu steuern. Wenn Sie an Mikro-Frontends arbeiten und eine Strategie zur Verwaltung von Abhängigkeiten entwickeln, kann die kaskadierende Funktion der Sprache eine Herausforderung sein.
Beispielsweise existieren zwei Mikro-Frontends nebeneinander auf derselben Seite, von denen jedes sein eigenes Styling für das HTML-Element definiert. body
Wenn jede Datei ihre eigene CSS-Datei abruft und sie mithilfe eines style
Tags an das DOM anhängt, überschreibt die CSS-Datei die erste, wenn beide Definitionen für gemeinsame HTML-Elemente, Klassennamen oder Element-IDs haben. Es gibt verschiedene Strategien, um mit diesen Problemen umzugehen, je nachdem, welche Abhängigkeitsstrategie Sie für die Verwaltung von Stilen wählen.
Derzeit besteht der beliebteste Ansatz, um Leistung, Konsistenz und Entwicklererfahrung in Einklang zu bringen, in der Entwicklung und Wartung eines Designsystems.
Designsysteme ‒ Ein Ansatz, bei dem man etwas teilen kann
Bei diesem Ansatz wird ein System verwendet, das bei Bedarf das Design gemeinsam nutzt und gleichzeitig gelegentliche Abweichungen unterstützt, um ein Gleichgewicht zwischen Konsistenz, Leistung und Entwicklererfahrung herzustellen. Ein Designsystem ist eine Sammlung wiederverwendbarer Komponenten, die sich an klaren Standards orientieren. Die Entwicklung eines Designsystems wird in der Regel von einem Team mit Beiträgen und Beiträgen von vielen Teams vorangetrieben. In der Praxis ist ein Designsystem eine Möglichkeit, Elemente auf niedriger Ebene gemeinsam zu nutzen, die als JavaScript Bibliothek exportiert werden können. Mikro-Frontend-Entwickler können die Bibliothek als Abhängigkeit verwenden, um einfache Schnittstellen zu erstellen, indem sie vorgefertigte verfügbare Ressourcen zusammenstellen, und als Ausgangspunkt für die Erstellung neuer Schnittstellen.
Stellen Sie sich das Beispiel eines Mikro-Frontends vor, das ein Formular benötigt. Die typische Entwicklererfahrung besteht darin, vorgefertigte Komponenten zu verwenden, die im Designsystem verfügbar sind, um Textfelder, Schaltflächen, Dropdownlisten und andere Benutzeroberflächenelemente zusammenzustellen. Der Entwickler muss kein Styling für die eigentlichen Komponenten schreiben, sondern nur dafür, wie sie zusammen aussehen. Das System, das erstellt und veröffentlicht werden soll, kann Webpack Module Federation oder einen ähnlichen Ansatz verwenden, um das Designsystem als externe Abhängigkeit zu deklarieren, sodass die Logik des Formulars verpackt wird, ohne das Designsystem einzubeziehen.
Mehrere Mikrofrontends können dann dasselbe tun, um gemeinsame Anliegen zu lösen. Wenn Teams neue Komponenten entwickeln, die von mehreren Mikrofrontends gemeinsam genutzt werden können, werden diese Komponenten dem Designsystem hinzugefügt, sobald sie ausgereift sind.
Ein Hauptvorteil des Designsystem-Ansatzes ist das hohe Maß an Konsistenz. Mikro-Frontends können zwar Stile schreiben und gelegentlich solche aus dem Designsystem überschreiben, aber das ist kaum erforderlich. Die wichtigsten Elemente auf niedriger Ebene ändern sich nicht oft und bieten grundlegende Funktionen, die standardmäßig erweiterbar sind. Ein weiterer Vorteil ist die Leistung. Mit einer guten Strategie für die Erstellung und Veröffentlichung können Sie eine minimale Anzahl gemeinsam genutzter Bundles erstellen, die von der Anwendungsshell instrumentiert werden. Sie können sich sogar noch weiter verbessern, wenn mehrere Micro-Frontend-spezifische Bundles bei Bedarf asynchron geladen werden, und das bei minimalem Platzbedarf in Bezug auf die Netzwerkbandbreite. Nicht zuletzt ist das Entwicklererlebnis ideal, da sich die Benutzer darauf konzentrieren können, umfangreiche Benutzeroberflächen zu erstellen, ohne das Rad neu zu erfinden (wie das Schreiben JavaScript und CSS jedes Mal, wenn einer Seite eine Schaltfläche hinzugefügt werden muss).
Der Nachteil ist, dass ein Designsystem jeglicher Art eine Abhängigkeit ist und daher gewartet und manchmal aktualisiert werden muss. Wenn mehrere Mikro-Frontends eine neue Version einer gemeinsamen Abhängigkeit erfordern, können Sie eine der folgenden Optionen verwenden:
-
Ein Orchestrierungsmechanismus, der gelegentlich mehrere Versionen dieser gemeinsamen Abhängigkeit ohne Konflikte abrufen kann
-
Eine gemeinsame Strategie, um alle abhängigen Benutzer auf eine neue Version umzustellen
Wenn beispielsweise alle Mikro-Frontends von der Version 3.0 eines Designsystems abhängen und es eine neue Version namens 3.1 gibt, die gemeinsam verwendet werden soll, können Sie Feature-Flags für alle Mikrofrontends implementieren, um sie mit minimalem Risiko zu migrieren. Weitere Informationen finden Sie im Abschnitt Feature-Flags. Ein weiterer potenzieller Nachteil besteht darin, dass Designsysteme in der Regel mehr als nur das Styling berücksichtigen. Sie beinhalten auch JavaScript Praktiken und Tools. Diese Aspekte erfordern, dass durch Debatte und Zusammenarbeit ein Konsens erzielt wird.
Die Implementierung eines Designsystems ist eine gute langfristige Investition. Es ist ein beliebter Ansatz und sollte von jedem in Betracht gezogen werden, der an einer komplexen Frontend-Architektur arbeitet. In der Regel müssen Frontend-Ingenieure sowie Produkt- und Designteams zusammenarbeiten und Mechanismen definieren, um miteinander zu interagieren. Es ist wichtig, Zeit einzuplanen, bis der gewünschte Zustand erreicht ist. Es ist auch wichtig, von der Unternehmensleitung unterstützt zu werden, damit die Mitarbeiter etwas aufbauen können, das zuverlässig, gut gewartet und langfristig leistungsfähig ist.
Vollständig gekapseltes CSS ‒ Ein Share-Nothing-Ansatz
Jedes Mikro-Frontend verwendet Konventionen und Tools, um die kaskadierende Funktion von CSS zu überwinden. Ein Beispiel ist die Sicherstellung, dass der Stil jedes Elements immer mit einem Klassennamen und nicht mit der ID des Elements verknüpft ist und Klassennamen immer eindeutig sind. Auf diese Weise ist alles auf individuelle Mikrofrontends zugeschnitten und das Risiko unerwünschter Konflikte wird minimiert. Die Anwendungsshell ist in der Regel dafür zuständig, die Stile der Mikrofrontends zu laden, nachdem sie in das DOM geladen wurden. Einige Tools bündeln die Stile jedoch mithilfe von JavaScript
Der Hauptvorteil, wenn nichts geteilt wird, ist das geringere Risiko, dass Konflikte zwischen Mikrofrontends entstehen. Ein weiterer Vorteil ist die Erfahrung des Entwicklers. Jedes Mikro-Frontend hat nichts mit anderen Micro-Frontends gemeinsam. Isoliertes Releasen und Testen ist einfacher und schneller.
Ein Hauptnachteil des Share-Nothing-Ansatzes ist der potenzielle Mangel an Konsistenz. Es gibt kein System zur Bewertung der Kohärenz. Auch wenn das Ziel darin besteht, gemeinsam genutzte Inhalte zu duplizieren, wird es schwierig, die Geschwindigkeit der Veröffentlichung und die Zusammenarbeit unter einen Hut zu bringen. Eine gängige Abhilfemaßnahme besteht darin, Tools zur Messung der Konsistenz zu entwickeln. Sie können beispielsweise ein System erstellen, mit dem automatisierte Screenshots mehrerer Mikrofrontends erstellt werden, die auf einer Seite mit einem Headless-Browser gerendert werden. Sie können die Screenshots dann vor einer Veröffentlichung manuell überprüfen. Dies erfordert jedoch Disziplin und Steuerung. Weitere Informationen finden Sie im Abschnitt Balance zwischen Autonomie und Ausrichtung.
Je nach Anwendungsfall ist ein weiterer potenzieller Nachteil die Leistung. Wenn von allen Mikrofrontends eine große Menge an Styling verwendet wird, muss der Kunde viel doppelten Code herunterladen. Das wird sich negativ auf die Benutzererfahrung auswirken.
Dieser Share-Nothing-Ansatz sollte nur für Mikro-Frontend-Architekturen in Betracht gezogen werden, an denen nur wenige Teams beteiligt sind, oder für Mikro-Frontends, die eine geringe Konsistenz vertragen. Es kann auch ein natürlicher erster Schritt sein, während eine Organisation an einem Designsystem arbeitet.
Gemeinsames globales CSS ‒ Ein Ansatz, bei dem alle gemeinsam genutzt werden
Bei diesem Ansatz wird der gesamte Code, der sich auf das Styling bezieht, in einem zentralen Repository gespeichert, in dem die Mitwirkenden CSS für alle Mikrofrontends schreiben, indem sie an CSS-Dateien arbeiten oder Präprozessoren wie Sass verwenden. Wenn Änderungen vorgenommen werden, erstellt ein Build-System ein einzelnes CSS-Bundle, das in einem CDN gehostet und von der Anwendungsshell in jedes Mikro-Frontend aufgenommen werden kann. Micro-Frontend-Entwickler können ihre Anwendungen entwerfen und erstellen, indem sie ihren Code über eine lokal gehostete Anwendungsshell ausführen.
Neben dem offensichtlichen Vorteil, das Risiko von Konflikten zwischen Mikrofrontends zu verringern, liegen die Vorteile dieses Ansatzes in Konsistenz und Leistung. Durch die Entkopplung von Stilen von Markup und Logik ist es für Entwickler jedoch schwieriger zu verstehen, wie Stile verwendet werden, wie sie sich weiterentwickeln können und wie sie veraltet sein können. Zum Beispiel könnte es schneller sein, einen neuen Klassennamen einzuführen, als etwas über die bestehende Klasse und die Folgen der Bearbeitung ihrer Eigenschaften zu erfahren. Zu den Nachteilen der Erstellung eines neuen Klassennamens gehören die Zunahme der Paketgröße, was sich auf die Leistung auswirkt, und die Gefahr von Inkonsistenzen in der Benutzererfahrung.
Ein gemeinsames globales CSS kann zwar der Ausgangspunkt einer monolith-to-micro-frontends Migration sein, ist aber für Mikro-Frontend-Architekturen, bei denen mehr als ein oder zwei Teams zusammenarbeiten, selten von Vorteil. Wir empfehlen, so bald wie möglich in ein Designsystem zu investieren und während der Entwicklung des Designsystems einen Share-Nothing-Ansatz zu implementieren.