Deutsch

Entfesseln Sie die Kraft von Micro-Frontends mit JavaScript Module Federation in Webpack 5. Lernen Sie, wie man skalierbare, wartbare und unabhängige Webanwendungen erstellt.

JavaScript Module Federation mit Webpack 5: Ein umfassender Leitfaden für Micro-Frontends

In der sich ständig weiterentwickelnden Landschaft der Webentwicklung kann die Erstellung großer und komplexer Anwendungen eine gewaltige Aufgabe sein. Traditionelle monolithische Architekturen führen oft zu längeren Entwicklungszeiten, Bereitstellungsengpässen und Schwierigkeiten bei der Aufrechterhaltung der Codequalität. Micro-Frontends haben sich als leistungsstarkes Architekturmuster herauskristallisiert, um diese Herausforderungen zu bewältigen, indem sie Teams ermöglichen, unabhängige Teile einer größeren Webanwendung zu erstellen und bereitzustellen. Eine der vielversprechendsten Technologien zur Implementierung von Micro-Frontends ist JavaScript Module Federation, eingeführt in Webpack 5.

Was sind Micro-Frontends?

Micro-Frontends sind ein Architekturstil, bei dem eine Frontend-App in kleinere, unabhängige Einheiten zerlegt wird, die von verschiedenen Teams autonom entwickelt, getestet und bereitgestellt werden können. Jedes Micro-Frontend ist für eine bestimmte Geschäftsdomäne oder ein Feature verantwortlich und wird zur Laufzeit zusammengesetzt, um die vollständige Benutzeroberfläche zu bilden.

Stellen Sie es sich wie ein Unternehmen vor: Anstatt eines riesigen Entwicklungsteams haben Sie mehrere kleinere Teams, die sich auf bestimmte Bereiche konzentrieren. Jedes Team kann unabhängig arbeiten, was schnellere Entwicklungszyklen und eine einfachere Wartung ermöglicht. Denken Sie an eine große E-Commerce-Plattform wie Amazon; verschiedene Teams könnten den Produktkatalog, den Warenkorb, den Bezahlvorgang und die Benutzerkontenverwaltung betreuen. All dies könnten unabhängige Micro-Frontends sein.

Vorteile von Micro-Frontends:

Herausforderungen von Micro-Frontends:

Was ist JavaScript Module Federation?

JavaScript Module Federation ist eine Funktion von Webpack 5, die es Ihnen ermöglicht, Code zwischen separat kompilierten JavaScript-Anwendungen zur Laufzeit zu teilen. Sie ermöglicht es Ihnen, Teile Ihrer Anwendung als „Module“ bereitzustellen, die von anderen Anwendungen konsumiert werden können, ohne sie in einem zentralen Repository wie npm veröffentlichen zu müssen.

Stellen Sie sich Module Federation als eine Möglichkeit vor, ein föderiertes Ökosystem von Anwendungen zu schaffen, in dem jede Anwendung ihre eigene Funktionalität beisteuern und Funktionalität von anderen Anwendungen konsumieren kann. Dies eliminiert die Notwendigkeit von Build-Zeit-Abhängigkeiten und ermöglicht wirklich unabhängige Deployments.

Zum Beispiel kann ein Design-System-Team UI-Komponenten als Module bereitstellen, und verschiedene Anwendungsteams können diese Komponenten direkt von der Design-System-Anwendung konsumieren, ohne sie als npm-Pakete installieren zu müssen. Wenn das Design-System-Team die Komponenten aktualisiert, spiegeln sich die Änderungen automatisch in allen konsumierenden Anwendungen wider.

Schlüsselkonzepte der Module Federation:

Einrichtung der Module Federation mit Webpack 5: Eine praktische Anleitung

Lassen Sie uns ein praktisches Beispiel für die Einrichtung der Module Federation mit Webpack 5 durchgehen. Wir erstellen zwei einfache Anwendungen: eine Host-Anwendung und eine Remote-Anwendung. Die Remote-Anwendung wird eine Komponente bereitstellen, und die Host-Anwendung wird sie konsumieren.

1. Projekteinrichtung

Erstellen Sie zwei separate Verzeichnisse für Ihre Anwendungen: `host` und `remote`.

```bash mkdir host remote cd host npm init -y npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev npm install react react-dom cd ../remote npm init -y npm install webpack webpack-cli webpack-dev-server html-webpack-plugin --save-dev npm install react react-dom ```

2. Konfiguration der Remote-Anwendung

Erstellen Sie im `remote`-Verzeichnis die folgenden Dateien:

src/index.js:

```javascript import React from 'react'; import ReactDOM from 'react-dom/client'; import RemoteComponent from './RemoteComponent'; const App = () => (

Remote Application

); const root = ReactDOM.createRoot(document.getElementById('root')); root.render(); ```

src/RemoteComponent.jsx:

```javascript import React from 'react'; const RemoteComponent = () => (

This is a Remote Component!

Rendered from the Remote Application.

); export default RemoteComponent; ```

webpack.config.js:

```javascript const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const path = require('path'); module.exports = { entry: './src/index', mode: 'development', devServer: { port: 3001, static: { directory: path.join(__dirname, 'dist'), }, }, output: { publicPath: 'auto', }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react', '@babel/preset-env'], }, }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: 'remote', filename: 'remoteEntry.js', exposes: { './RemoteComponent': './src/RemoteComponent', }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true }, }, }), new HtmlWebpackPlugin({ template: './public/index.html', }), ], resolve: { extensions: ['.js', '.jsx'], }, }; ```

Erstellen Sie `public/index.html` mit einer grundlegenden HTML-Struktur. Wichtig ist `

`

3. Konfiguration der Host-Anwendung

Erstellen Sie im `host`-Verzeichnis die folgenden Dateien:

  • `src/index.js`: Einstiegspunkt für die Anwendung.
  • `webpack.config.js`: Webpack-Konfigurationsdatei.

src/index.js:

```javascript import React, { Suspense } from 'react'; import ReactDOM from 'react-dom/client'; const RemoteComponent = React.lazy(() => import('remote/RemoteComponent')); const App = () => (

Host Application

Loading Remote Component...
}>
); const root = ReactDOM.createRoot(document.getElementById('root')); root.render(); ```

webpack.config.js:

```javascript const HtmlWebpackPlugin = require('html-webpack-plugin'); const ModuleFederationPlugin = require('webpack/lib/container/ModuleFederationPlugin'); const path = require('path'); module.exports = { entry: './src/index', mode: 'development', devServer: { port: 3000, static: { directory: path.join(__dirname, 'dist'), }, }, output: { publicPath: 'auto', }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-react', '@babel/preset-env'], }, }, }, ], }, plugins: [ new ModuleFederationPlugin({ name: 'host', remotes: { remote: 'remote@http://localhost:3001/remoteEntry.js', }, shared: { react: { singleton: true, eager: true }, 'react-dom': { singleton: true, eager: true }, }, }), new HtmlWebpackPlugin({ template: './public/index.html', }), ], resolve: { extensions: ['.js', '.jsx'], }, }; ```

Erstellen Sie `public/index.html` mit einer grundlegenden HTML-Struktur (ähnlich der Remote-App). Wichtig ist `

`

4. Babel installieren

Installieren Sie in beiden Verzeichnissen, `host` und `remote`, die Babel-Abhängigkeiten:

```bash npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loader ```

5. Ausführen der Anwendungen

Fügen Sie in beiden Verzeichnissen, `host` und `remote`, das folgende Skript zu `package.json` hinzu:

```json "scripts": { "start": "webpack serve" } ```

Starten Sie nun beide Anwendungen:

```bash cd remote npm start cd ../host npm start ```

Öffnen Sie Ihren Browser und navigieren Sie zu `http://localhost:3000`. Sie sollten die Host-Anwendung sehen, in der die Remote-Komponente gerendert wird.

Erläuterung der wichtigsten Konfigurationsoptionen:

Fortgeschrittene Techniken der Module Federation

Module Federation bietet viele fortgeschrittene Funktionen, die Ihnen helfen können, noch anspruchsvollere Micro-Frontend-Architekturen zu erstellen.

Dynamische Remotes

Anstatt die URLs von Remote-Anwendungen fest in der Webpack-Konfiguration zu codieren, können Sie sie zur Laufzeit dynamisch laden. Dies ermöglicht es Ihnen, den Speicherort von Remote-Anwendungen einfach zu aktualisieren, ohne die Host-Anwendung neu erstellen zu müssen.

Sie könnten beispielsweise die URLs von Remote-Anwendungen in einer Konfigurationsdatei oder einer Datenbank speichern und sie dynamisch mit JavaScript laden.

```javascript // In webpack.config.js remotes: { remote: `promise new Promise(resolve => { const urlParams = new URLSearchParams(window.location.search); const remoteUrl = urlParams.get('remote'); // Assume remoteUrl is something like 'http://localhost:3001/remoteEntry.js' const script = document.createElement('script'); script.src = remoteUrl; script.onload = () => { // the key of module federation is that the remote app is // available using the name in the remote resolve(window.remote); }; document.head.appendChild(script); })`, }, ```

Jetzt können Sie die Host-App mit einem Abfrageparameter `?remote=http://localhost:3001/remoteEntry.js` laden

Versionierte geteilte Module

Module Federation kann die Versionierung und Deduplizierung von geteilten Modulen automatisch handhaben, um sicherzustellen, dass nur eine kompatible Version jedes Moduls geladen wird. Dies ist besonders wichtig bei großen und komplexen Anwendungen mit vielen Abhängigkeiten.

Sie können den Versionsbereich jedes geteilten Moduls in der Webpack-Konfiguration angeben.

```javascript // In webpack.config.js shared: { react: { singleton: true, eager: true, requiredVersion: '^18.0.0' }, 'react-dom': { singleton: true, eager: true, requiredVersion: '^18.0.0' }, }, ```

Benutzerdefinierte Modul-Loader

Module Federation ermöglicht es Ihnen, benutzerdefinierte Modul-Loader zu definieren, die verwendet werden können, um Module aus verschiedenen Quellen oder in verschiedenen Formaten zu laden. Dies kann nützlich sein, um Module von einem CDN oder aus einem benutzerdefinierten Modulregister zu laden.

Zustandsfreigabe (State Sharing) zwischen Micro-Frontends

Eine der Herausforderungen von Micro-Frontend-Architekturen ist die gemeinsame Nutzung des Zustands (State) zwischen verschiedenen Micro-Frontends. Es gibt mehrere Ansätze, die Sie verfolgen können, um diese Herausforderung zu bewältigen:

Best Practices für die Implementierung von Micro-Frontends mit Module Federation

Hier sind einige bewährte Methoden, die Sie bei der Implementierung von Micro-Frontends mit Module Federation beachten sollten:

Praxisbeispiele für Module Federation im Einsatz

Obwohl spezifische Fallstudien oft vertraulich sind, sind hier einige verallgemeinerte Szenarien, in denen Module Federation unglaublich nützlich sein kann:

Fazit

JavaScript Module Federation in Webpack 5 bietet eine leistungsstarke und flexible Möglichkeit, Micro-Frontend-Architekturen zu erstellen. Sie ermöglicht es Ihnen, Code zwischen separat kompilierten JavaScript-Anwendungen zur Laufzeit zu teilen, was unabhängige Deployments, technologische Vielfalt und verbesserte Teamautonomie ermöglicht. Indem Sie die in diesem Leitfaden beschriebenen bewährten Methoden befolgen, können Sie Module Federation nutzen, um skalierbare, wartbare und innovative Webanwendungen zu erstellen.

Die Zukunft der Frontend-Entwicklung neigt zweifellos zu modularen und verteilten Architekturen. Module Federation bietet ein entscheidendes Werkzeug für den Bau dieser modernen Systeme und ermöglicht es Teams, komplexe Anwendungen mit größerer Geschwindigkeit, Flexibilität und Widerstandsfähigkeit zu erstellen. Mit der Weiterentwicklung der Technologie können wir erwarten, dass noch mehr innovative Anwendungsfälle und bewährte Praktiken entstehen werden.