Microfrontends unter Realbedingungen
Vor einigen Jahren, als der Hype um Microfrontends Fahrt aufnahm, blieb ich an einer Formulierung hängen:
TRUE independent teams
TRUE war tatsächlich vollständig großgeschrieben.
Das klang verdächtig nach Marketing. Trotzdem hat mich der Satz beschäftigt. Denn echte Unabhängigkeit von Teams ist ein starkes Architekturversprechen: Ein Team versteht sein System, verändert es, testet es, veröffentlicht es und betreibt es, ohne für jeden Schritt auf den Rest der Plattform warten zu müssen.
Ich begann, mich intensiver mit Microfrontends und den Konzepten dahinter zu beschäftigen. Dabei habe ich unter anderem viel von Manfred Steyer und Rainer Hahnekamp gelesen. Je länger ich mich mit dem Thema befasste, desto weniger interessant wurde allerdings die Frage, wie man das erste Remote lädt.
Interessanter wurde, was danach passiert.
Kein weiteres Getting Started
Abschnitt betitelt „Kein weiteres Getting Started“Diese Serie ist keine Anleitung nach dem Muster:
So baust du einen Host und drei Remotes.
Wer Microfrontends oder Module Federation mit Nx technisch aufsetzen möchte, findet dafür eine offizielle Anleitung in der Nx-Dokumentation.
Die technische Initialisierung ist der vergleichsweise einfache Teil. Generatoren und vorhandene Integrationen nehmen einem heute vieles ab, was früher noch mühsam konfiguriert werden musste.
Mein Rat aus Erfahrung: Schreib dafür nicht vorschnell eine eigene Lösung.
Eine Sonderkonfiguration kann sinnvoll sein. Sie sollte nur ein Problem lösen, das tatsächlich existiert. Sonst entsteht aus ein paar vermeintlich einfachen Einstellungen erstaunlich schnell eine kleine Plattform, die fortan ebenfalls versioniert, getestet und verstanden werden möchte.
Diese Serie beginnt deshalb nicht beim ersten erfolgreichen Build.
Sie beginnt dort, wo der Host läuft und die einfachen Folien aufhören.
Warum diese Serie entstanden ist
Abschnitt betitelt „Warum diese Serie entstanden ist“Microfrontends werden häufig über ihre technische Form erklärt: Host, Remotes, Module Federation, Runtime Loading, getrennte Builds.
Das beschreibt den Mechanismus. Es beantwortet noch nicht die Architekturfrage.
Unter Realbedingungen geht es um andere Dinge: Wer darf was verändern? Welche Grenzen sind wirklich unabhängig? Wem gehören Daten, URLs, UI und Geschäftsprozesse? Was passiert, wenn ein Remote ausfällt? Wie lassen sich verschiedene Versionen gleichzeitig betreiben? Wie wird ein Release abgenommen, ohne jedes Mal das gesamte Produkt aufzubauen? Und wie viel zusätzliche Infrastruktur und Koordination ist die gewonnene Autonomie eigentlich wert?
Dabei zeigt sich schnell, dass viele vermeintlich technische Probleme in Wahrheit Ownership-Probleme sind.
Ein Remote kann separat deploybar sein und trotzdem auf das Shell-Team warten. Zwei Teams können getrennte Repositories besitzen und trotzdem nur gemeinsam releasen. Ein System kann fünf Remotes enthalten und organisatorisch weiterhin ein Monolith sein.
Die Architektur ist dann verteilt. Die Abhängigkeiten haben lediglich neue Adressen bekommen.
Was in den folgenden Artikeln passiert
Abschnitt betitelt „Was in den folgenden Artikeln passiert“Die Serie nähert sich Microfrontends deshalb nicht über ein Referenzdiagramm, sondern über die Entscheidungen, die in einem echten Produkt irgendwann getroffen werden müssen.
Am Anfang stehen die Grenzen selbst: Welches Problem soll die Verteilung lösen? Wie groß darf ein Microfrontend werden? Wann ist ein Remote eine fachliche Capability – und wann nur eine aufwendig ausgelieferte Komponentenbibliothek?
Danach wird die Integration unbequemer. Remotes müssen miteinander auskommen, obwohl sie möglichst wenig voneinander wissen sollen. Frameworks und Versionen können auseinanderlaufen. Die URL braucht trotzdem einen Besitzer, die Oberfläche soll wie ein Produkt wirken und globale technische Fähigkeiten dürfen nicht heimlich zur nächsten fachlichen Kopplung werden.
Spätestens bei Authentifizierung, Ausfällen und Tests reicht das Architekturdiagramm endgültig nicht mehr. Ein unabhängiges Frontend muss auch dann noch sinnvoll funktionieren, wenn andere Teile fehlen. Es muss sich isoliert entwickeln und abnehmen lassen, ohne dafür seine Umgebung nachzubauen.
Und irgendwann steht das System in Produktion.
Dann geht es um unveränderliche Artefakte, Produktkompositionen, parallele Versionen, kontrollierte Aktivierung, Rollbacks, Observability und die recht einfache Supportfrage:
Welche Anwendung hat dieser Benutzer eigentlich gerade gesehen?
Zum Schluss bleibt die wirtschaftliche und organisatorische Perspektive. Repository-Grenzen, Plattformteams, zusätzliche Infrastruktur und unabhängige Releases haben einen Preis. Migration ist deshalb kein Selbstzweck – und eine gute Microfrontend-Strategie braucht genauso eine Antwort auf die Frage, wann man mit der Zerlegung aufhört.
Unabhängigkeit unter Realbedingungen
Abschnitt betitelt „Unabhängigkeit unter Realbedingungen“Der rote Faden hinter all diesen Fragen bleibt derselbe:
Ein Frontend wird nicht allein dadurch unabhängig, dass sein Code in einem eigenen Remote liegt. Entscheidend ist, ob Teams ihre Systeme eigenständig verstehen, verändern, testen, veröffentlichen und betreiben können.
Das Ergebnis muss nicht immer ein Microfrontend sein.
Manchmal ist eine gemeinsame Abstraktion sinnvoll. Manchmal ist die Duplikation billiger. Manchmal bleibt ein modularer Monolith die bessere Architektur. Und manchmal kostet die zusätzliche Autonomie mehr, als sie dem Produkt jemals zurückgeben wird.
Microfrontends sind weder grundsätzlich überlegen noch grundsätzlich falsch.
Sie sind eine Architekturentscheidung mit Konsequenzen.
Diese Serie handelt von diesen Konsequenzen.