Von Workbox v5 zu v6 migrieren

In diesem Leitfaden geht es um funktionsgefährdende Änderungen, die in Workbox v6 eingeführt wurden. Außerdem finden Sie Beispiele für die Änderungen, die Sie beim Upgrade von Workbox v5 vornehmen müssen.

Funktionsgefährdende Änderungen

workbox-core

Die Methode skipWaiting() in workbox-core fügt keinen install-Handler mehr hinzu und entspricht dem Aufruf von self.skipWaiting().

Verwenden Sie ab jetzt stattdessen self.skipWaiting(), da skipWaiting() wahrscheinlich in Workbox v7 entfernt wird.

workbox-precaching

  • Ursprungsübergreifende HTML-Dokumente für URLs, die einer HTTP-Weiterleitung entsprechen, können nicht mehr verwendet werden, um eine Navigationsanfrage mit workbox-precaching zu erfüllen. Dieses Szenario ist im Allgemeinen selten.
  • Der URL-Suchparameter fbclid wird jetzt von workbox-precaching ignoriert, wenn eine im Cache gespeicherte Antwort für eine bestimmte Anfrage gesucht wird.
  • Der PrecacheController-Konstruktor verwendet jetzt ein Objekt mit bestimmten Eigenschaften als Parameter anstelle eines Strings. Dieses Objekt unterstützt die folgenden Properties: cacheName (dient demselben Zweck wie der String, der in v5 an den Konstruktor übergeben wurde), plugins (ersetzt die Methode addPlugins() aus v5) und fallbackToNetwork (ersetzt die ähnliche Option, die in v5 an createHandler() und `createHandlerBoundToURL() übergeben wurde).
  • Die Methoden install() und activate() von PrecacheController akzeptieren jetzt genau einen Parameter, der auf einen entsprechenden InstallEvent bzw. ActivateEvent festgelegt werden sollte.
  • Die Methode addRoute() wurde aus PrecacheController entfernt. Stattdessen kann die neue Klasse PrecacheRoute verwendet werden, um eine Route zu erstellen, die Sie dann registrieren können.
  • Die Methode precacheAndRoute() wurde aus PrecacheController entfernt. (Sie ist weiterhin als statische Hilfsmethode vorhanden, die vom Modul workbox-precaching exportiert wird.) Sie wurde entfernt, weil stattdessen PrecacheRoute verwendet werden kann.
  • Die Methode createMatchCalback() wurde aus PrecacheController entfernt. Stattdessen kann die neue PrecacheRoute verwendet werden.
  • Die Methode createHandler() wurde aus PrecacheController entfernt. Stattdessen kann die Property strategy des Objekts PrecacheController verwendet werden, um Anfragen zu verarbeiten.
  • Der statische Export createHandler() wurde bereits aus dem Modul workbox-precaching entfernt. Stattdessen sollten Entwickler eine PrecacheController-Instanz erstellen und deren strategy-Property verwenden.
  • Die bei precacheAndRoute() registrierte Route ist jetzt eine „echte“ Route, die im Hintergrund die Klasse Router von workbox-routing verwendet. Dies kann zu einer anderen Auswertungsreihenfolge Ihrer Routen führen, wenn Sie Aufrufe von registerRoute() und precacheAndRoute() verschachteln.

workbox-routing

Die Methode setDefaultHandler() akzeptiert jetzt einen optionalen zweiten Parameter, der der HTTP-Methode entspricht, auf die sie angewendet wird. Der Standardwert ist 'GET'.

  • Wenn Sie setDefaultHandler() verwenden und alle Ihre Anfragen GET sind, müssen Sie nichts ändern.
  • Wenn Sie Anfragen haben, die nicht GET (POST, PUT usw.) sind, setDefaultHandler() führt nicht mehr dazu, dass diese Anfragen übereinstimmen.

Build-Konfiguration

Die Option mode für die Modi getManifest und injectManifest in workbox-build und workbox-cli sollte nicht unterstützt werden und wurde entfernt. Dies gilt nicht für workbox-webpack-plugin, da mode im Plug-in InjectManifest unterstützt wird.

Build-Tools erfordern Node.js v10 oder höher

Node.js-Versionen vor v10 werden für workbox-webpack-plugin, workbox-build und workbox-cli nicht mehr unterstützt. Wenn Sie eine Node.js-Version vor v8 ausführen, aktualisieren Sie Ihre Laufzeit auf eine unterstützte Version.

Neue Verbesserungen

workbox-strategies

In Workbox v6 wird eine neue Möglichkeit für Drittanbieter eingeführt, eigene Workbox-Strategien zu definieren. So können Drittanbieter-Entwickler Workbox so erweitern, dass es ihren Anforderungen entspricht.

Neue Basisklasse für Strategien

In v6 müssen alle Workbox-Strategieklassen die neue Basisklasse Strategy erweitern. Alle integrierten Strategien wurden umgeschrieben, um dies zu unterstützen.

Die Basisklasse Strategy ist für zwei Hauptaufgaben verantwortlich:

  • Aufrufen von Plug-in-Lebenszyklus-Callbacks, die für alle Strategie-Handler gelten (z.B. wenn sie starten, antworten und enden).
  • Erstellen einer „Handler“-Instanz, die den Status für jede einzelne Anfrage verwalten kann, die von einer Strategie verarbeitet wird.

Neue „Handler“-Klasse

Zuvor haben wir interne Module fetchWrapper und cacheWrapper aufrufen lassen, die (wie der Name schon sagt) die verschiedenen Abruf- und Cache-APIs mit Hooks in ihren Lebenszyklus einbinden. Das ist der Mechanismus, der derzeit die Verwendung von Plug-ins ermöglicht, aber er ist für Entwickler nicht zugänglich.

Die neue „Handler“-Klasse StrategyHandler stellt diese Methoden bereit, sodass benutzerdefinierte Strategien fetch() oder cacheMatch() aufrufen können und alle Plugins, die der Strategieinstanz hinzugefügt wurden, automatisch aufgerufen werden.

Diese Klasse würde es Entwicklern auch ermöglichen, eigene benutzerdefinierte Lebenszyklus-Callbacks hinzuzufügen, die für ihre Strategien spezifisch sind, und sie würden „einfach so“ mit der vorhandenen Plug-in-Schnittstelle funktionieren.

Neuer Lebenszyklusstatus des Plug-ins

In Workbox v5 sind Plug-ins zustandslos. Wenn also eine Anfrage für /index.html sowohl den Callback requestWillFetch als auch den Callback cachedResponseWillBeUsed auslöst, können diese beiden Callbacks nicht miteinander kommunizieren oder auch nur erkennen, dass sie von derselben Anfrage ausgelöst wurden.

In v6 wird allen Plug-in-Callbacks auch ein neues state-Objekt übergeben. Dieses Zustandsobjekt ist für dieses bestimmte Plug-in-Objekt und diesen bestimmten Strategieaufruf (d.h. den Aufruf von handle()) eindeutig. So können Entwickler Plug-ins schreiben, bei denen ein Callback bedingt etwas tun kann, basierend auf dem, was ein anderer Callback im selben Plug-in getan hat (z.B. die Zeitdifferenz zwischen der Ausführung von requestWillFetch und fetchDidSucceed oder fetchDidFail berechnen).

Neue Lebenszyklus-Callbacks für Plug-ins

Es wurden neue Lebenszyklus-Callbacks für Plug-ins hinzugefügt, damit Entwickler den Lebenszyklusstatus von Plug-ins vollständig nutzen können:

  • handlerWillStart: wird aufgerufen, bevor die Handler-Logik ausgeführt wird. Mit diesem Callback kann der anfängliche Handler-Status festgelegt werden, z.B. die Startzeit.
  • handlerWillRespond: Wird aufgerufen, bevor die Methode handle() der Strategie eine Antwort zurückgibt. Mit diesem Callback kann die Antwort geändert werden, bevor sie an einen Routen-Handler oder eine andere benutzerdefinierte Logik zurückgegeben wird.
  • handlerDidRespond: Wird aufgerufen, nachdem die Methode handle() der Strategie eine Antwort zurückgegeben hat. Mit diesem Callback können alle endgültigen Antwortdetails aufgezeichnet werden, z.B. nach Änderungen durch andere Plug-ins.
  • handlerDidComplete: Wird aufgerufen, nachdem alle Promises zur Verlängerung der Lebensdauer, die dem Ereignis durch den Aufruf dieser Strategie hinzugefügt wurden, abgeschlossen sind. Mit diesem Callback können alle Daten gemeldet werden, die erst berechnet werden können, wenn der Handler fertig ist (z.B. Cache-Trefferstatus, Cache-Latenz, Netzwerklatenz).
  • handlerDidError: Wird aufgerufen, wenn der Handler keine gültige Antwort von einer Quelle bereitstellen konnte. Dieser Callback kann verwendet werden, um „Fallback“-Inhalte als Alternative zu einem Netzwerkfehler bereitzustellen.

Entwickler, die ihre eigenen benutzerdefinierten Strategien implementieren, müssen sich nicht um den Aufruf dieser Callbacks kümmern. Das wird alles von einer neuen Strategy-Basisklasse übernommen.

Genauere TypeScript-Typen für Handler

TypeScript-Definitionen für verschiedene Callback-Methoden wurden normalisiert. Das sollte die Arbeit für Entwickler, die TypeScript verwenden und eigenen Code zum Implementieren oder Aufrufen von Handlern schreiben, erleichtern.

workbox-window

Neue Methode „messageSkipWaiting()“

Dem Modul workbox-window wurde die neue Methode messageSkipWaiting() hinzugefügt, um den Prozess der Aktivierung des wartenden Service Workers zu vereinfachen. Das bietet einige Verbesserungen:

  • Es ruft postMessage() mit dem de facto standardmäßigen Inhalt der Nachricht {type: 'SKIP_WAITING'} auf, den ein von Workbox generierter Service Worker prüft, um skipWaiting() auszulösen.
  • Es wird der richtige „wartende“ Service Worker ausgewählt, an den diese Nachricht gesendet werden soll, auch wenn es sich nicht um denselben Service Worker handelt, bei dem workbox-window registriert wurde.

Entfernung von „externen“ Ereignissen zugunsten einer isExternal-Property

Alle externen Ereignisse in workbox-window wurden entfernt und durch „normale“ Ereignisse ersetzt, bei denen die Property isExternal auf true festgelegt ist. So können Entwickler, die Wert auf die Unterscheidung legen, diese weiterhin erkennen, und Entwickler, die sie nicht benötigen, können die Property ignorieren.

Saubereres Rezept „Nutzern das Aktualisieren der Seite anbieten“

Dank der beiden oben genannten Änderungen kann das Rezept Nutzern das Neuladen einer Seite anbieten vereinfacht werden:

// v6:
<script type="module">
  import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.0.0-alpha.1/workbox-window.prod.mjs';

  if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');

    const showSkipWaitingPrompt = () => {
      // This assumes a hypothetical createUIPrompt() method with
      // onAccept and onReject callbacks:
      const prompt = createUIPrompt({
        onAccept: () => {
          wb.addEventListener('controlling', () => {
            window.location.reload();
          });

          // This will postMessage() to the waiting service worker.
          wb.messageSkipWaiting();
        },

        onReject: () => {
          prompt.dismiss();
        },
      });
    };

    // Listening for externalwaiting is no longer needed.
    wb.addEventListener('waiting', showSkipWaitingPrompt);
    wb.register();
  }
</script>

workbox-routing

Ein neuer boolescher Parameter, sameOrigin, wird an die Funktion matchCallback übergeben, die in workbox-routing verwendet wird. Der Wert wird auf true gesetzt, wenn die Anfrage für eine Ursprungs-URL gilt, andernfalls auf „false“.

Dadurch werden einige gängige Boilerplates vereinfacht:

// In v5:
registerRoute(
  ({url}) =>
    url.origin === self.location.origin && url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'})
);

// In v6:
registerRoute(
  ({sameOrigin, url}) => sameOrigin && url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'})
);

matchOptions in workbox-expiration

Sie können jetzt matchOptions in workbox-expiration festlegen. Dieser Wert wird dann als CacheQueryOptions an den zugrunde liegenden cache.delete()-Aufruf übergeben. Die meisten Entwickler müssen dies nicht tun.

workbox-precaching

Verwendet Workbox-Strategien

workbox-precaching wurde so umgeschrieben, dass workbox-strategies als Basis verwendet wird. Dies sollte nicht zu funktionsgefährdenden Änderungen führen und langfristig zu einer besseren Konsistenz beim Zugriff der beiden Module auf das Netzwerk und den Cache führen.

Beim Precaching werden Einträge jetzt einzeln und nicht mehr im Bulk verarbeitet.

workbox-precaching wurde so aktualisiert, dass jeweils nur ein Eintrag im Precache-Manifest angefordert und im Cache gespeichert wird, anstatt zu versuchen, alle gleichzeitig anzufordern und im Cache zu speichern (wobei es dem Browser überlassen bleibt, wie er die Anfragen drosselt).

Dadurch sollte die Wahrscheinlichkeit von net::ERR_INSUFFICIENT_RESOURCES-Fehlern beim Precaching verringert werden. Außerdem sollte die Bandbreitenkonkurrenz zwischen Precaching und gleichzeitigen Anfragen der Web-App reduziert werden.

PrecacheFallbackPlugin ermöglicht einen einfacheren Offline-Fallback

workbox-precaching enthält jetzt eine PrecacheFallbackPlugin, die die neue Lebenszyklusmethode handlerDidError implementiert, die in Version 6 hinzugefügt wurde.

So lässt sich eine vorab im Cache gespeicherte URL ganz einfach als „Fallback“ für eine bestimmte Strategie angeben, wenn eine Antwort sonst nicht verfügbar wäre. Das Plug-in sorgt dafür, dass der richtige Cache-Schlüssel für die vorab im Cache gespeicherte URL erstellt wird, einschließlich aller erforderlichen Revisionsparameter.

Hier ist ein Beispiel dafür, wie Sie damit eine im Cache gespeicherte /offline.html-Datei zurückgeben, wenn die NetworkOnly-Strategie keine Antwort für eine Navigationsanfrage generieren kann. Mit anderen Worten: Es wird eine benutzerdefinierte Offline-HTML-Seite angezeigt:

import {PrecacheFallbackPlugin, precacheAndRoute} from 'workbox-precaching';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

// Ensure that /offline.html is part of your precache manifest!
precacheAndRoute(self.__WB_MANIFEST);

registerRoute(
  ({request}) => request.mode === 'navigate',
  new NetworkOnly({
    plugins: [
      new PrecacheFallbackPlugin({
        fallbackURL: '/offline.html',
      }),
    ],
  })
);

precacheFallback im Laufzeit-Caching

Wenn Sie generateSW verwenden, um einen Service Worker für Sie zu erstellen, anstatt ihn manuell zu schreiben, können Sie die neue Konfigurationsoption precacheFallback in runtimeCaching verwenden, um dasselbe zu erreichen:

{
  // ... other generateSW config options...
  runtimeCaching: [{
    urlPattern: ({request}) => request.mode === 'navigate',
    handler: 'NetworkOnly',
    options: {
      precacheFallback: {
        // This URL needs to be included in your precache manifest.
        fallbackURL: '/offline.html',
      },
    },
  }],
}

Hilfe erhalten

Wir gehen davon aus, dass die meisten Migrationen unkompliziert sind. Wenn Sie auf Probleme stoßen, die in diesem Leitfaden nicht behandelt werden, öffnen Sie bitte ein Problem auf GitHub.