Von Workbox v4 zu v5 migrieren

In diesem Leitfaden geht es um die in Workbox 5 eingeführten nicht abwärtskompatiblen Änderungen. Außerdem finden Sie hier Beispiele für Änderungen, die Sie beim Upgrade von Workbox 4 vornehmen müssen.

Wichtige Änderungen

Plug-in-Klassen umbenannt

Eine Reihe von Workbox v4-Paketen enthielten Klassen mit dem Namen Plugin. In Version 5 wurden diese Klassen umbenannt, sodass sie der Musterpaket-ID + Plugin folgen:

  • BackgroundSyncPlugin
  • BroadcastUpdatePlugin
  • CacheableResponsePlugin
  • ExpirationPlugin
  • RangeRequestsPlugin

Diese Umbenennung gilt unabhängig davon, ob Sie die Klassen über Modulimporte oder über die workbox.*-Namespaces verwenden.

Standard-Ersatzpunkt für Precache-Manifest

Früher bei Verwendung eines der Build-Tools in „Manifest einfügen“ wurde Ihre Quelldienst-Worker-Datei auf das Vorhandensein von precacheAndRoute([]) geprüft. Dabei wurde das leere Array [] als Platzhalter für den Punkt verwendet, an dem das Precache-Manifest eingeschleust wurde.

In Workbox v5 wurde die Ersatzlogik geändert. Jetzt wird standardmäßig self.__WB_MANIFEST als Injection Point verwendet.

// v4:
precacheAndRoute([]);

// v5:
precacheAndRoute(self.__WB_MANIFEST);

Wie in dieser Diskussion erläutert, ist diese Änderung unserer Meinung nach einfacher und bietet Entwicklern gleichzeitig mehr Kontrolle darüber, wie das eingeblendete Manifest im benutzerdefinierten Service Worker-Code verwendet wird. Bei Bedarf können Sie diesen Ersatzstring über die Konfigurationsoption injectionPoint ändern.

Die beiden Optionen blacklist und whitelist, die zuvor für Navigationsrouten unterstützt wurden, wurden in denylist und allowlist umbenannt.

workbox-routing unterstützte bisher die Methode registerNavigationRoute(), die im Hintergrund zwei Dinge tat:

  1. Es wurde erkannt, ob für ein bestimmtes fetch-Ereignis ein mode von 'navigate' aufgetreten ist.
  2. Falls ja, antworten Sie auf die Anfrage mit dem Inhalt einer zuvor zwischengespeicherten, hartcodierten URL, unabhängig von der URL, zu der navigiert wird.

Dieses Muster wird häufig bei der Implementierung der App Shell-Architektur verwendet.

Der zweite Schritt, das Generieren einer Antwort durch Lesen aus dem Cache, fällt nicht in den Zuständigkeitsbereich von workbox-routing. Stattdessen sehen wir dies als Funktion, die über die neue Methode createHandlerBoundToURL() Teil von workbox-precaching sein sollte. Diese neue Methode kann mit der vorhandenen NavigationRoute-Klasse in workbox-routing zusammenarbeiten, um dieselbe Logik zu erreichen.

Wenn Sie die Option navigateFallback in einem der Build-Tools zum Generieren von Software verwenden erfolgt der Wechsel automatisch. Wenn Sie zuvor die Optionen navigateFallbackBlacklist oder navigateFallbackWhitelist konfiguriert haben, ändern Sie diese in navigateFallbackDenylist bzw. navigateFallbackAllowlist.

Bei Verwendung von „insertmanifest“ oder den Service Worker einfach selbst schreiben und der Workbox v4-Service Worker registerNavigationRoute() direkt aufruft, müssen Sie eine Änderung an Ihrem Code vornehmen, um das entsprechende Verhalten zu erreichen.

// v4:
import {getCacheKeyForURL} from 'workbox-precaching';
import {registerNavigationRoute} from 'workbox-routing';

const appShellCacheKey = getCacheKeyForURL('/app-shell.html');
registerNavigationRoute(appShellCacheKey, {
  whitelist: [...],
  blacklist: [...],
});

// v5:
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';

const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
  allowlist: [...],
  denylist: [...],
});
registerRoute(navigationRoute);

Du musst getCacheKeyForURL() nicht mehr anrufen. Das übernimmt createHandlerBoundToURL() für dich.

Entfernung von makeRequest() aus workbox-strategies

Der Aufruf von makeRequest() entspricht im Wesentlichen dem Aufruf von handle() für eine der workbox-strategy-Klassen. Die Unterschiede zwischen den beiden Methoden waren so gering, dass es keinen Sinn machte, beide zu behalten. Entwickler, die makeRequest() aufgerufen haben, sollten ohne weitere Änderungen zu handle() wechseln können:

// v4:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.makeRequest({event, request});

// v5:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.handle({event, request});

In Version 5 wird request in handle() als erforderlicher Parameter behandelt und es wird nicht auf event.request zurückgegriffen. Achte darauf, beim Aufrufen von handle() eine gültige Anfrage zu übergeben.

„workbox-broadcast-update“ verwendet immer postMessage()

In Version 4 verwendete die workbox-broadcast-update-Bibliothek standardmäßig die Broadcast Channel API zum Senden von Nachrichten, wenn diese unterstützt wurde. Wenn Broadcast Channel nicht unterstützt wurde, wurde nur postMessage() verwendet.

Wir stellten fest, dass das Schreiben von clientseitigem Code zu kompliziert wurde, weil wir zwei mögliche Quellen eingehender Nachrichten abhören mussten. Außerdem werden in einigen Browsern postMessage()-Aufrufe vom Service Worker, die an Clientseiten gesendet werden, automatisch zwischengespeichert, bis ein message-Event-Listener eingerichtet wird. Mit der Broadcast Channel API findet keine Zwischenspeicherung statt und Broadcast-Nachrichten werden einfach verworfen, wenn sie gesendet werden, bevor eine Client-Seite für den Empfang bereit ist.

Aus diesem Grund haben wir workbox-broadcast-update geändert, sodass in Version 5 immer postMessage() verwendet wird. Nachrichten werden einzeln an alle Clientseiten im Geltungsbereich des aktuellen Service Workers gesendet.

Um diesem neuen Verhalten gerecht zu werden, können Sie jeglichen Code auf Clientseiten entfernen, auf denen BroadcastChannel-Instanzen erstellt wurden, und stattdessen einen message-Event-Listener für navigator.serviceWorker einrichten:

// v4:
const updatesChannel = new BroadcastChannel('api-updates');
updatesChannel.addEventListener('message', event => {
  const {cacheName, updatedUrl} = event.data.payload;
  // ... your code here ...
});

// v5:
// This listener should be added as early as possible in your page's lifespan
// to ensure that messages are properly buffered.
navigator.serviceWorker.addEventListener('message', event => {
  // Optional: ensure the message came from workbox-broadcast-update
  if (event.meta === 'workbox-broadcast-update') {
    const {cacheName, updatedUrl} = event.data.payload;
    // ... your code here ...
  }
});

workbox-window-Nutzer sollten keine Änderungen vornehmen müssen, da die interne Logik aktualisiert wurde, um postMessage()-Aufrufe zu erkennen.

Für Build-Tools ist Node.js v8 oder höher erforderlich

Node.js-Versionen vor Version 8 werden für workbox-webpack-plugin, workbox-build und workbox-cli nicht mehr unterstützt. Wenn Sie eine ältere Node.js-Version als 8 verwenden, aktualisieren Sie Ihre Laufzeit auf eine unterstützte Version.

Workbox-webpack-plugin erfordert Webpack v4 oder höher

Wenn du workbox-webpack-plugin verwendest, aktualisiere deine Webpack-Einrichtung, um mindestens Webpack v4 zu verwenden.

Überarbeitung der Build-Tool-Optionen

Einige Konfigurationsparameter workbox-build, workbox-cli und workbox-webpack-plugin werden nicht mehr unterstützt. generateSW erstellt beispielsweise immer ein lokales Workbox-Laufzeit-Bundle für Sie, sodass die Option importWorkboxFrom nicht mehr sinnvoll ist.

Eine Liste der unterstützten Optionen finden Sie in der Dokumentation des jeweiligen Tools.

Entfernen von „generateSWString“ aus „workbox-build“

Der Modus „generateSWString“ wurde aus „workbox-build“ entfernt. Wir gehen davon aus, dass die Auswirkungen minimal sind, da sie hauptsächlich intern von workbox-webpack-plugin verwendet wurde.

Optionale Änderungen

Modulimporte verwenden

Während diese Änderung a) optional und b) technisch möglich war, wenn Workbox v4 verwendet wurde, ist die größte Änderung, die wir beim Wechsel zu v5 erwarten, ein Modell, bei dem Sie Ihren eigenen gebündelten Service Worker erstellen, indem Sie die Workbox-Module importieren. Dieser Ansatz ist eine Alternative zum Aufrufen von importScripts('/path/to/workbox-sw.js') oben in Ihrem Service Worker und zur Verwendung von Workbox über den Namespace workbox.*.

Wenn Sie eines der Build-Tools (workbox-webpack-plugin, workbox-build, workbox-cli) in „Software generieren“ verwenden aktiviert haben, wird diese Änderung automatisch für Sie übernommen. Alle diese Tools geben ein lokales, benutzerdefiniertes Bundle der Workbox-Laufzeit zusammen mit dem Code aus, der zur Implementierung Ihrer Service Worker-Logik erforderlich ist. In diesem Szenario besteht keine Abhängigkeit mehr von workbox-sw oder der CDN-Kopie von Workbox. Abhängig vom Wert Ihrer inlineWorkboxRuntime-Konfiguration wird die Workbox-Laufzeit entweder in eine separate Datei aufgeteilt, die zusammen mit Ihrem Service Worker bereitgestellt werden sollte (wenn der Standardwert false ist), oder sie wird inline in die Service Worker-Logik eingefügt (bei Einstellung auf true).

Bei Verwendung der Build-Tools in „Manifest einfügen“ oder wenn Sie die Build-Tools von Workbox überhaupt nicht verwenden, finden Sie im Leitfaden Using Bundlers (Webpack/Rollup) with Workbox (Bundlers (Webpack/Rollup) mit Workbox verwenden) weitere Informationen zum Erstellen Ihres eigenen Workbox-Laufzeit-Bundles.

Die Dokumentation und Beispiele für Version 5 gehen davon aus, dass die Syntax für Modulimporte verwendet wird. Der Namespace workbox.* wird jedoch auch in Workbox 5 weiterhin unterstützt.

Vorab im Cache gespeicherte Antworten lesen

Einige Entwickler müssen vorab im Cache gespeicherte Antworten direkt aus dem Cache lesen, anstatt sie implizit über die precacheAndRoute()-Methode zu verwenden. Ein gängiges Muster in v4 wäre, zuerst den Cache-Schlüssel für die aktuelle Version einer vorab im Cache gespeicherten Ressource abzurufen und diesen Schlüssel dann zusammen mit dem Cache-Namen des Precaches an caches.match() zu übergeben, um das Response zu erhalten.

Zur Vereinfachung unterstützt workbox-precaching in Version 5 eine neue, äquivalente Methode, matchPrecache():

// v4:
import {cacheNames} from 'workbox-core';
import {getCacheKeyForURL} from 'workbox-precaching';

const cachedResponse = await caches.match(
  getCacheKeyForURL(`/somethingPrecached`),
  {
    cacheName: cacheNames.precache,
  }
);

// v5:
import {matchPrecache} from 'workbox-precaching';

const cachedResponse = await matchPrecache(`/somethingPrecached`);

TypeScript-Akzeptanz

In Version 5 sind die Workbox-Laufzeitbibliotheken in TypeScript geschrieben. Wir werden zwar weiterhin transpilierte JavaScript-Module und -Bundles für Entwickler veröffentlichen, die TypeScript nicht verwenden, sollten jedoch von genauen und immer aktuellen Typinformationen direkt aus dem Workbox-Projekt profitieren, wenn Sie TypeScript verwenden.

Beispiel für eine Migration

Dieses Commit stellt eine recht aufwendige Migration mit Inline-Kommentaren dar. Dabei wird Rollup verwendet, um eine benutzerdefinierte Workbox-Laufzeit in den endgültigen Service Worker einzubinden, anstatt die Laufzeit aus dem CDN zu laden.

Hier sehen Sie vor und nach dem Upgrade einer Service Worker-Datei von Version 4 auf Version 5, einschließlich des Wechsels zu TypeScript. Nicht alle bahnbrechenden Änderungen werden abgedeckt.

Hilfe erhalten

Wir gehen davon aus, dass die meisten Migrationen unkompliziert ablaufen. Wenn Probleme auftreten, die in dieser Anleitung nicht behandelt werden, eröffnen Sie ein Problem auf GitHub.