Micro Frontends bringen die Idee von Microservices ins Frontend

Den Monolith fachgerecht zerlegen
Keine Kommentare

Micro Frontends oder auch Micro Apps werden in letzter Zeit häufiger diskutiert. Nachdem Microservices-Architekturen im Backend wachsenden Anklang finden, schwappt dieser Architekturansatz auch immer öfter ins Frontend. Das erste Mal wurden Micro Frontends im ThoughtWorks Technology Radar Ende 2016 erwähnt. Seit dieser Zeit haben sich zahlreiche Bibliotheken und Hilfsmittel rund um diesen Architekturansatz entwickelt.

Vor dem Einsatz dieser Architekturform sollten Sie sich fragen, ob Micro Frontends die richtige Lösung für Ihre Applikation sind. Analog zum Blogartikel von Dan Abramov zum Einsatz der State-Management-Bibliothek Redux „You might not need Redux“ steht auch vor der Implementierung einer Applikation mit Micro Frontends diese Aussage im Raum „You might not need Micro Frontends“. Diese Architekturform hat ihre Vor- und Nachteile, die Sie gegeneinander abwiegen sollten. Die Micro-Frontend-Architektur stellt eine grundlegende Architekturentscheidung dar. Diese im Nachhinein umzustellen, gestaltet sich aufwendig.

Der Gegenentwurf zu einer Micro-Frontend-Architektur ist der klassische Monolith. Eine monolithische Applikation besteht aus einer zusammenhängenden Codestruktur. Das muss jedoch nicht zwingend bedeuten, dass es sich um unstrukturierten Spaghetticode handelt. Ein moderner Monolith weist eine modulare Struktur auf, sodass auch hier zahlreiche Vorteile einer Services-Architektur, wenn auch in abgeschwächtem Ausmaß, greifen. Das Ziel von Modularisierung und auch von Micro Frontends ist, in sich geschlossene Teile einer Applikation zu isolieren. Im Backend geht die Microservices-Architektur einen Schritt weiter und entkoppelt die einzelnen Module vollständig voneinander, sodass einzelne Prozesse entstehen, die getrennt voneinander entwickelt, veröffentlicht und gewartet werden können. Mit Micro Frontends halten viele dieser Vorteile auch Einzug ins Frontend.

Die Vorteile von Micro Frontends

Einer der Vorteile von Microservices im Backend ist, dass Sie diese Services unabhängig voneinander skalieren können, indem Sie zusätzliche Instanzen der Services hochfahren. Dieses Feature ist bei Microservices im Frontend nicht relevant, da es sich bei den Services nicht um Prozesse, sondern mehr um eigenständige Bausteine des Frontends handelt.

Micro Frontends spielen ihre wahre Stärke in der Entkopplung dieser Bausteine über die Grenzen einer bloßen Modularisierung aus. Die einzelnen Micro Frontends können ihre eigenen Technologiestacks und internen Architekturen aufweisen. Eine Applikation mit einer Micro-Frontend-Architektur kann sich also beispielsweise aus einem Angular-Frontend, einem React-Frontend und einem Vue-Frontend zusammensetzen. Jedes dieser Frontends kann von einem eigenständigen Team umgesetzt werden. Damit lassen sich komplette Featureteams realisieren, die sich vom Backend bis zum Frontend durchziehen. Jedes Team ist damit in der Lage, Features in ihrer Gesamtheit umzusetzen und zu releasen, ohne dass die übrige Applikation in Mitleidenschaft gezogen wird.

Die Schattenseiten von Micro Frontends

Im Gegensatz zu einem modularisierten Frontend-Monolithen, dessen Kern in der Regel eine Bibliothek bildet, kann sich eine Applikation mit Micro Frontends aus verschiedenen Bibliotheken zusammensetzen. Dem Vorteil der technischen Freiheit steht hier der entscheidende Nachteil eines deutlich erhöhten Transfervolumens entgegen. Diesem Nachteil kann zum Teil durch die Optimierung der Pakete, Komprimierung der Übertragung und Lazy Loading entgegengewirkt werden.

International PHP Conference

Entwickler – das verlorene Handbuch

by Stefan Priebsch (thePHP.cc)

My browser does what?

by Joel Lord (Red Hat OpenShift

Nicht nur das erhöhte Volumen, sondern auch potenziell stark unterschiedliche Strukturen in den einzelnen Teilen der Applikation stellen ein Problem dar. So wird der Wechsel zwischen den Micro Frontends durch unterschiedliche Architekturansätze oder die Verwendung verschiedener Frameworks erschwert. Dies macht sich gerade dann bemerkbar, wenn die verschiedenen Teile des Frontends von einem Team gewartet werden müssen. Die Entwickler müssen dann den Überblick über die verschiedenen Technologien und ihre Eigenheiten haben. Diesem Problem können Sie in Ihrer Applikation durch Konventionen und eine strikte Qualitätskontrolle begegnen. Durch Vorgaben hinsichtlich Technologien und Bibliotheken schränken Sie zwar die Freiheit der Entwickler etwas ein, die Wartbarkeit der Applikation wird dadurch jedoch potenziell erhöht.

Zu guter Letzt bringt die Micro-Frontend-Architektur selbst noch den Nachteil einer erhöhten Gesamtkomplexität der Applikation mit sich. Der Grund hierfür liegt darin, dass eine Basis für die Micro Frontends geschaffen werden muss. Serverseitig werden Microservices meist in Containern deployt und von einer Softwarekomponente orchestriert. Clientseitig stellt der Browser die Laufzeitumgebung der Micro Frontends dar. Diese müssen in eine zentrale HTML-Seite eingebunden werden, damit ein Benutzer mit der Applikation interagieren kann. Für die Integration der verschiedenen Frontend Services existieren verschiedene Ansätze, von denen ich Ihnen einige im Laufe dieses Artikels vorstellen möchte. Allen Lösungen ist gemein, dass sie eine mehr oder weniger umfangreiche Abstraktionsschicht erforderlich machen.

Vorbedingungen

Angesichts der Nachteile einer Micro-Frontend-Architektur sollten Sie eine solche Architekturentscheidung nicht leichtfertig treffen. Ihre Applikation sollte zumindest einige Anforderungen erfüllen:

  • Umfangreicher Funktionsumfang: Durch die erhöhte Komplexität spielt eine Micro-Frontend-Architektur ihre Vorteile erst ab einem bestimmten Funktionsumfang aus. Je größer die Applikation und je mehr gut voneinander abgrenzbare Features sie aufweist, desto besser.
  • Getrennte Entwicklungsteams: Mit Micro Frontends lassen sich Microservices von der Datenbank über das Backend bis ins Frontend umsetzen. Den Teams wird dadurch ein hohes Maß an Autonomie zugesprochen und auch Releases können unabhängig voneinander erfolgen.
  • Unterschiedliche Technologien oder Bibliotheken: Häufig lassen sich Probleme durch spezialisierte Lösungen besser lösen. Eine Micro-Frontend-Architektur gewährt hier deutlich mehr Freiheiten als ein monolithischer Ansatz.

Mögliche Lösungsansätze

Die zahlreichen Lösungsansätze unterscheiden sich durch die verwendeten Technologien, den Aufwand bei der Umsetzung und die Integrierbarkeit der verschiedenen Lösungen. Grundsätzlich können mehrere Frameworks und Bibliotheken auf einer HTML-Seite eingebunden werden. Der Nachteil ist, dass die Build-Prozesse der einzelnen Lösungen nicht hierauf ausgerichtet sind und es gerade bei komplexeren Applikationen zu Problemen kommen kann. Auch die Integration der einzelnen Applikationen kann aufwendig sein.

Mehrere Applikationen über iFrames einbinden

Geht es nur darum, mehrere Frameworks auf einer Seite zu betreiben, ist der einfachste Ansatz die Verwendung von iFrames. Ein iFrame erlaubt die Einbindung einer HTML-Seite in eine andere. Dabei kann die eingebundene Applikation nicht direkt auf den Kontext der Basisapplikation zugreifen, sie wird also in einer Art Sandbox ausgeführt. Eine einfache Kommunikation zwischen beiden Applikationsteilen ist über Nachrichten möglich. Bei dieser Lösung bleiben die einzelnen Micro Frontends der Applikation vollständig unabhängig voneinander. Namens- oder Strukturkonflikte sowie eine gegenseitige Beeinflussung durch Stylesheets sind ausgeschlossen. Die Integrationsschicht, also die Basisseite, die selbst eine Single Page Application sein kann, muss sich um die Anzeige und Positionierung der iFrames kümmern. Je nachdem, wie aufwendig diese Integrationsschicht gehalten ist, entstehen wiederum Abhängigkeiten zu den einzelnen Applikationen, die unabhängige Releases erschweren. Ein Beispiel für solche Abhängigkeiten ist die bedingte Anzeige einer Applikation. Eine Bedingung kann beispielsweise lauten: Applikation A, die in Vue implementiert ist, wird nur angezeigt, wenn der Pfad im URL /list lautet; Applikation B, eine React-Applikation, wird nur angezeigt, wenn der Pfad /details aktiv ist. Über einen kleinen Umweg über das History API des iFrames kann sogar der Router der jeweiligen Applikation angesprochen werden. Aber auch dies erhöht die Kopplung zwischen Integrationsschicht und der Applikation, da die Integrationsschicht Details über die Implementierung kennen muss, hier das Vorhandensein eines Routers.

In bestimmten Fällen kann die Implementierung einer solchen iFrame-Lösung durchaus Sinn ergeben – bei einer zeitlich begrenzten Migration einer Applikation auf eine neue technische Basis beispielsweise. Für den Dauerbetrieb aber gibt es für diese Problemstellung wesentlich elegantere Lösungsansätze.

Eigene Implementierung mit Web Components

Im Zusammenhang mit Micro Frontends fällt häufig der Begriff Web Components. Unter diesem Begriff wird eine Sammlung von Browserschnittstellen zusammengefasst, die einen komponentenbasierten Aufbau einer Applikation ermöglichen. Im Kern bestehen Web Components aus Custom Elements, dem Shadow DOM und HTML-Templates.

Mit einem Custom Element können Sie den Vorrat der HTML-Tags, die dem Browser bekannt sind, erweitern. Ein solches Element definieren Sie in JavaScript als eine Klasse, die von der Basisklasse HTMLElement ableitet. Das Shadow DOM ermöglicht eine Entkopplung der Komponente von der übrigen Applikation. Dies wird erreicht, indem sowohl die DOM-Struktur der Komponente als auch die Styles komplett eigenständig sind. Wird die Komponente in die Applikation eingebunden, ist sichergestellt, dass keine unerwünschten Seiteneffekte von anderen Elementen einwirken. HTML-Templates erlauben, wie der Name vermuten lässt, Strukturtemplates. Mit ihnen entfällt die Notwendigkeit, manuell Strukturvorlagen zu erzeugen und diese zu verwalten. Stattdessen steht mit einem HTML-Template eine Struktur zur Verfügung, die mittels JavaScript in der Web Component gerendert werden kann. In Listing 1 sehen Sie ein Beispiel für eine solche Web Component.

<template id="helloWorldTemplate">
  <h1>Hello World</h1>
</template>;

class HelloWorld extends HTMLElement {
  constructor() {
    super();

    const template = document.querySelector('#helloWorldTemplate');

    this.attachShadow({ mode: 'open' }).appendChild(
      template.content.cloneNode(true)
    );
  }
}

customElements.define('hello-world', HelloWorld);

Im ersten Teil der Web Component sehen Sie ein einfaches Template, das ein h1-Tag mit Text enthält. Dieses Template wird im einfachsten Fall direkt in die HTML-Struktur der Applikation eingebettet. Die Klasse HelloWorld wird von der HTMLElement-Klasse abgeleitet, die vom Browser zur Verfügung gestellt wird. Im Konstruktor wird mit der attachShadow-Methode das Shadow DOM für diese Komponente aktiviert und mit dem Inhalt des Templates befüllt. Der letzte Bestandteil, das Custom Element, wird mit der customElements.define-Methode definiert. Mit diesem Quellcode können Sie dann das <hello-world>-Tag in Ihrer Applikation verwenden und so die Web Component einbinden. Diese Konzepte und Schnittstellen können auch die Grundlage für die Integrationsschicht Ihrer Micro-Frontend-Architektur bilden. Dabei wird jedes Micro Frontend als eigene Web Component eingebunden. Angular Elements sind die Lösung von Angular für diesen Ansatz. Dabei werden Angular-Komponenten in Web Components gepackt und können dann verwendet werden. Für Vue existiert eine Erweiterung der CLI, um Vue-Komponenten ebenfalls in Web Components zu wrappen. Lediglich bei React müssen Sie sich selbst um einen solchen Wrapper kümmern. Dieser ist allerdings in wenigen Zeilen implementiert.

Web Components mit Angular

Eine Web Component lässt sich mit Hilfe der Angular Elements erzeugen. Als Beispiel für ein Micro Frontend mit Angular erzeugen wir eine einfache Beispielapplikation, transformieren diese in eine Web Component und binden diese in eine Applikation ein. Zunächst initialisieren Sie Ihre Applikation mit der Angluar CLI. Anschließend fügen Sie das für die Angular Elements erforderliche Polyfill mit dem Befehl ng add @angular/elements hinzu. Für das Beispiel reicht eine einfache Komponente bereits aus, die im Template lediglich ein h1-Element mit dem Text „Hello Angular“ aufweist.

Der wichtigste Teil geschieht im zentralen Modul der Applikation. Hier erzeugen Sie das Custom Element mit der createCustomElement aus dem Angular-Elements-Paket. Dieses Custom Element registrieren Sie wie eine gewöhnliche Web Component, mit der customElements.define-Methode. Listing 2 enthält den Quellcode des App-Moduls mit der Registrierung der Komponente.

import { BrowserModule } from '@angular/platform-browser';
import { NgModule, Injector } from '@angular/core';
import { createCustomElement } from '@angular/elements';

import { HelloAngularComponent } from './hello-angular/hello-angular.component';

@NgModule({
  declarations: [HelloAngularComponent],
  imports: [BrowserModule],
  entryComponents: [HelloAngularComponent],
})
export class AppModule {
  constructor(private injector: Injector) {
    const helloAngular = createCustomElement(HelloAngularComponent, {
      injector,
    });
    customElements.define('hello-angular', helloAngular);
  }

  ngDoBootstrap() {}
}

Bauen Sie nun Ihre Applikation mit dem Kommando ng build –prod –output-hashing none, erhalten Sie eine Reihe von Dateien im dist-Verzeichnis. Binden Sie nun die Dateien main.js, polyfills.js, runtime.js und scripts.js in Ihre Applikation ein, können Sie das Custom Element nutzen. In Listing 3 sehen Sie den erforderlichen Code.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Angular Web Component</title>
    <script src="dist/main.js"></script>
    <script src="dist/polyfills.js"></script>
    <script src="dist/runtime.js"></script>
    <script src="dist/scripts.js"></script>
  </head>
  <body>
    <hello-angular></hello-angular>
  </body>
</html>

Damit Ihre Applikation funktioniert, müssen Sie die Dateien, die Sie mit dem Buildprozess erzeugt haben, in die index.html-Datei einbinden. Anschließend können Sie das Custom Element verwenden.

Web Components mit React

React unterstützt Web Components nicht direkt. Es existieren jedoch zahlreiche Communityprojekte, die Sie bei der Erzeugung von Wrappern für Ihre React-Komponenten unterstützten. Alternativ können Sie auch selbst einen solchen Wrapper erzeugen.

Ein solcher Wrapper besteht im Kern aus einer Web Component, die Sie in Form einer eigenständigen Klasse implementieren, die von der HTMLElement-Klasse ableitet. Innerhalb der connectedCallback-Methode, die ausgeführt wird, sobald die Komponente zum ersten Mal mit dem DOM verbunden wird, kümmern Sie sich um die Erzeugung der React-Strukturen. Zunächst erzeugen Sie ein Wurzelelement, an das Sie Ihre React-Applikation binden. Außerdem aktivieren Sie das Shadow DOM und rendern schließlich die Applikation mit der render-Methode des ReactDOM-Objekts. Im letzten Schritt definieren Sie das Custom Element mit der define-Methode des customElements-Objekts. Anschließend können Sie Ihre Web Component nutzen. In Listing 4 finden Sie den Quellcode des React Web Component Wrappers.

class HelloWorld extends HTMLElement {
  connectedCallback() {
    const mountPoint = document.createElement('span');
    this.attachShadow({ mode: 'open' }).appendChild(mountPoint);

    ReactDOM.render(<HelloWorld />, mountPoint);
  }
}
customElements.define('react-hello-world', HelloWorld);

Eine weitere Lösung zur Implementierung einer Applikation mit einer Micro-Frontend-Architektur ist das Framework single-spa.

single-spa

Beschäftigen Sie sich mit Micro Frontends, werden Sie früher oder später mit dem Framework single-spa konfrontiert. Dieses Framework ist, wie viele andere JavaScript-Lösungen auch, ein Open-Source-Projekt, das auf GitHub verwaltet wird. Die Entwicklung begann Ende 2015 und es wird nach wie vor aktiv weiterentwickelt. Neben der Projektseite auf GitHub ist der Einstieg in single-spa die Webseite des Projekts. Die Entwickler des Frameworks werben damit, dass Sie bei der Verwendung von single-spa die freie Wahl zwischen unterschiedlichen Frameworks für Ihre Applikation haben und so Angular, Vue und React friedlich nebeneinander existieren können. Außerdem wird Lazy Loading unterstützt, was die Ladezeit der Applikation erheblich verbessern kann, da die einzelnen Bestandteile erst geladen werden, wenn sie wirklich gebraucht werden.

Wie in den anderen Ansätzen besteht auch eine single-spa-Applikation aus mehreren Teilen. In diesem Fall gibt es mit der single-spa-config eine Integrationsschicht, in die die einzelnen Micro Frontends eingebunden werden. Die Micro Frontends sind reguläre Single-Page-Applikationen, die durch das Framework zu einer Gesamtapplikation integriert werden.

Installation und erste Schritte

Das single-spa-Framework ist modular aufgebaut. Den Kern bildet das single-spa-Paket. Es bildet die Grundlage Ihrer Applikation und stellt die Integrationsschicht dar. In diese werden dann die verschiedenen Micro Frontends integriert. Bevor Sie jedoch mit der Installation des Pakets beginnen, sollten Sie eine package.json-Datei für Ihre Applikation erzeugen, in der Sie alle installierten Abhängigkeiten festhalten. Die package.json-Datei erzeugen Sie mit dem Kommando npm init -y. Nach der Ausführung dieses Kommandos können Sie das single-spa-Paket mit dem Befehl npm install single-spa installieren. Für die Frameworks und Bibliotheken, die die Grundlage der einzelnen Micro Frameworks bilden, existieren weitere Pakete. So installieren Sie für ein React Micro Frontend beispielsweise das single-spa-react-Paket. Bei der Gestaltung der einzelnen Applikationsteile sind Sie recht frei. Sie können die gesamte Applikation in einer Verzeichnisstruktur verwalten, mit Unterverzeichnissen für die einzelnen Micro Frontends, oder Sie implementieren die einzelnen Teile in separaten Projekten und nutzen einen Paketmanager wie npm oder yarn, um die Applikation zusammenzufügen.

Zunächst widmen wir uns jedoch dem Aufbau der Integrationsschicht. Diese besteht aus einer HTML-Datei, die den Einstiegspunkt in die Applikation markiert. Diese Datei weist lediglich eine Reihe von Containerelementen auf, in die die Micro Frontends eingehängt werden. Zusätzlich dazu erzeugen Sie eine JavaScript-Datei, die die Konfiguration der Applikation enthält. Die Konfiguration funktioniert ähnlich wie beim JavaScript-Build-System Gulp über Funktionsaufrufe. Im Fall von single-spa sind dies die Funktionen registerApplication und start. Die registerApplication-Funktion aus dem single-spa-Paket dient zur Registrierung einer Applikation. Das erste Argument ist der Name der registrierten Applikation, das zweite eine Funktion, die aufgerufen wird, wenn die Applikation das erste Mal geladen wird. Diese Funktion, die auch als loadingFunction bezeichnet wird, muss ein Promise-Objekt zurückgeben, das mit dem Quellcode der Applikation aufgelöst wird. Das dritte Argument, das Sie an die registerApplication-Funktion übergeben, ist die activityFunction Funktion. Diese gibt an, ob die Applikation aktiviert werden soll. Diese Funktion erhält als Argument das window.location-Objekt. Über dieses haben Sie beispielsweise Zugriff auf den aktuellen Pfad.

Damit die Applikation korrekt gebaut werden kann, benötigen Sie einen Build-Prozess, für den Sie die Werkzeuge webpack und babel benötigen. webpack dient zum Bundling der Applikation und Babel zur Umsetzung bestimmter Features wie beispielsweise dem ECMAScript-Modulsystem. Beispiele für die .babelrc– und webpack.config.js-Datei finden Sie in der Dokumentation von single-spa. In Listing 5 finden Sie die package.json für die Integrationsschicht.

{
  "name": "microfrontends",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "directories": {
    "test": "test"
  },
  "scripts": {
    "start": "webpack-dev-server --open",
    "build": "webpack --config webpack.config.js -p"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "single-spa": "^4.1.1"
  },
  "devDependencies": {
    "@babel/core": "^7.3.4",
    "@babel/plugin-proposal-object-rest-spread": "^7.3.4",
    "@babel/plugin-syntax-dynamic-import": "^7.2.0",
    "@babel/preset-env": "^7.3.4",
    "@babel/preset-react": "^7.0.0",
    "babel-loader": "^8.0.5",
    "clean-webpack-plugin": "^2.0.1",
    "css-loader": "^2.1.1",
    "html-loader": "^0.5.5",
    "style-loader": "^0.23.1",
    "webpack": "^4.29.6",
    "webpack-cli": "^3.3.0",
    "webpack-dev-server": "^3.2.1"
  }
}

In der package.json-Datei finden Sie neben den allgemeinen Informationen zur Applikation und den installierten Abhängigkeiten noch zwei Einträge unter dem Punkt scripts. Mit dem Kommando npm start starten Sie den Webpack Dev Server für den Entwicklungsprozess. Der Befehl npm run build dient zum Bauen der Applikation.

React-Applikation in single-spa

Jedes Micro Frontend in single-spa benötigt einen leichtgewichtigen Wrapper um die eigentliche Applikation, sodass sie sich über die Integrationsschicht in die Applikation einbinden lässt. Für die React-Applikation erzeugen Sie zunächst ein neues Verzeichnis mit dem Namen react-app. In diesem Verzeichnis erzeugen Sie ebenfalls eine package.json-Datei, da jedes Micro Frontend als eigenständige Applikation betrachtet werden kann. Anschließend installieren Sie mit dem Kommando npm install react react-dom single-spa-react React selbst sowie die Hilfsbibliothek für die Integration der Applikation in single-spa. Für die Integration erzeugen Sie eine Datei mit dem Namen react.app.js. Diese Datei übernimmt das Bootstrapping, Mounting und Unmounting der Applikation. Listing 6 zeigt den Quellcode dieser Datei.

import React from 'react';
import ReactDOM from 'react-dom';
import singleSpaReact from 'single-spa-react';
import App from './App.js';

function domElementGetter() {
  return document.getElementById('react-app');
}

const reactLifecycles = singleSpaReact({
  React,
  ReactDOM,
  rootComponent: App,
  domElementGetter,
});

export const bootstrap = [reactLifecycles.bootstrap];

export const mount = [reactLifecycles.mount];

export const unmount = [reactLifecycles.unmount];

Der singleSpaReact-Funktion, die Sie aus dem single-spa-react-Paket importieren, übergeben Sie ein Objekt mit Referenzen auf React und ReactDOM. Außerdem definieren Sie die Wurzelkomponente der Applikation über die Eigenschaft rootComponent. Mit der Eigenschaft domElementGetter übergeben Sie eine Funktion, die eine Referenz auf das Containerelement, in das die Applikation eingebunden werden soll, zurückliefert. Die Datei exportiert die drei Variablen bootstrap, mount und unmount. Die Werte dieser Variablen sind jeweils Arrays, die als Inhalte die entsprechende Lifecycle-Methode enthalten, die Ihnen das reactLifecycles-Objekt zur Verfügung stellt. Dieses Objekt ist der Rückgabewert der singleSpaReact-Funktion. Die Komponente, die Sie der rootComponent übergeben, ist eine gewöhnliche React-Komponente. Das bedeutet, dass Sie hier auf alle Features von React zurückgreifen können. Es ist an dieser Stelle beispielsweise auch möglich, den React Router einzubinden und so innerhalb der Applikation über URLs zu navigieren.

Ein letzter Punkt, der nun noch offen ist, ist die Einbindung der Applikation in die loadingFunction in der Integrationsschicht. Hier nutzen Sie die import-Funktion und übergeben ihr den Pfad zur react.app.js-Datei.

Angular-Applikation in single-spa

Ähnlich wie mit React funktioniert auch die Integration einer Angular-Applikation. In diesem Fall haben Sie die Möglichkeit, entweder mit dem Angular CLI oder, analog zum Beispiel mit React, ohne das CLI zu arbeiten. Falls Sie sich für die Variante mit dem CLI entscheiden, müssen Sie zunächst das Angular CLI mit dem Kommando npm install -g @angular/cli installieren. Anschließend erzeugen Sie eine neue Applikation mit dem Kommando ng new angular-app. Auch hier müssen Sie eine Hilfsbibliothek installieren; dies erreichen Sie mit dem Kommando npm install single-spa-angular-cli. Im Gegensatz zu den übrigen single-spa-Paketen, mit denen Sie bisher gearbeitet haben, wird dieses Paket nicht direkt vom single-spa-Team entwickelt, stattdessen handelt es sich hierbei um ein Communityprojekt.

Die Konfiguration der Hilfsbibliothek erfolgt wie für das React Micro Frontend. Sie importieren den Loader aus dem single-spa-angular-cli-Projekt und konfigurieren ihn, um die Lifecycles für das Bootstrapping, Mounting und Unmounting zu erhalten. Bei der Konfiguration übergeben Sie den Namen der Applikation, den Selektor für das Wurzeltag, sowie optional den Selektor für den HTML-Container. Die letzte Option ist die baseHref für Ihre Angular-Applikation. Listing 7 enthält den erforderlichen Quellcode.

import { loader } from 'single-spa-angular-cli';

const lifecycles = loader({
  name: 'hello-angular',
  selector: 'hello-angular',
  baseHref: '/angular',
});

export const bootstrap = [lifecycles.bootstrap];

export const mount = [lifecycles.mount];

export const unmount = [lifecycles.unmount];

export const unload = [lifecycles.unload];

Neben React und Angular werden noch zahlreiche weitere populäre JavaScript Frameworks unterstützt, unter anderem AngularJS, Ember, Preact oder Vue. Die Vorgehensweise ist bei allen Frameworks dieselbe: Sie installieren die Hilfsbibliothek, die die Integration in single-spa ermöglicht, konfigurieren sie und starten dann mit der Entwicklung Ihrer Applikation.

Fazit

Micro Frontends bringen die Idee von Microservices ins Frontend. Einige Vorteile von Microservices spielen im Frontend keine Rolle. So ist es beispielsweise irrelevant, einzelne Services zu skalieren. Andere Vorteile spielen Micro Frontends ebenfalls aus. So können mehrere Teams an einer Applikation arbeiten, ohne dass Probleme entstehen. Die einzelnen Micro Frontends können unabhängig voneinander entwickelt werden, jedes Team hat die Möglichkeit, seine eigenen Technologien auswählen und einsetzen. Ist die Integrationsschicht der Applikation richtig gewählt, können die einzelnen Teile der Applikation auch unabhängig voneinander veröffentlicht werden.

Mit dieser Integrationsschicht steht und fällt die Flexibilität der Micro-Frontend-Architektur. Hier stehen Ihnen verschiedenen Varianten zur Umsetzung zur Verfügung, diese reichen von der Verwendung von iFrames über den Einsatz von Web Components bis hin zur Implementierung einer Applikation auf Basis von Bibliotheken wie single-spa.

Gerade Frameworks wie single-spa stellen eine vielversprechende Lösung für eine Micro-Frontend-Architektur dar. Durch seinen modularen Charakter ist single-spa nicht auf ein einzelnes JavaScript Framework oder einen manuellen Web Component Wrapper angewiesen. Die Integrationsschicht ist vergleichsweise leichtgewichtig gehalten und kann um zusätzliche Framework-spezifische Pakete erweitert werden. Jedes Micro Frontend, das Sie in Ihre single-spa-Applikation integrieren möchten, benötigt eine Konfiguration, die als Adapter bei der Registrierung in die Integrationsschicht fungiert. Zur Erzeugung einer solchen Konfiguration können Sie auf eine Reihe von vorgefertigten Lösungen wie beispielsweise das single-spa-vue-Paket zurückgreifen, das die Integration einer Vue-Applikation erlaubt. Bis auf diese Konfiguration handelt es sich bei den Micro-Frontend-Applikationen um reguläre Applikationen, die mit einer angepassten Konfiguration auch ohne single-spa lauffähig sind.

Trotz aller Vorteile und der Tatsache, dass die Micro-Frontend-Architektur gerade in aller Munde ist, sollten Sie sich sehr genau überlegen, ob Sie Ihre Applikation auf diese Architektur aufbauen möchten. Durch die separate Integrationsschicht und die Verwendung verschiedener Technologien erhöht sich die Komplexität der Applikation erheblich. Die Durchsetzung einheitlicher Styles sowie die Vorgabe von Design- und Architekturmustern ist nur schwer möglich. Oft lässt sich eine Anwendung auch als gut modularisierter Monolith mit einer geringeren Komplexität umsetzen.

PHP Magazin

Entwickler MagazinDieser Artikel ist im PHP Magazin erschienen. Das PHP Magazin deckt ein breites Spektrum an Themen ab, die für die erfolgreiche Webentwicklung unerlässlich sind.

Natürlich können Sie das PHP Magazin über den entwickler.kiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen. In unserem Shop ist das Entwickler Magazin ferner im Abonnement oder als Einzelheft erhältlich.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
400
  Subscribe  
Benachrichtige mich zu:
X
- Gib Deinen Standort ein -
- or -