Workbox-Fenster verwenden

Ein Workbox-Modul, das in dieser Dokumentation noch nicht umfassend behandelt wurde, ist workbox-window. Es besteht aus einer Reihe von Modulen, die in window ausgeführt werden sollen. Die Ziele dieses Moduls sind:

  • Die Registrierung und Aktualisierung von Service Workern wird vereinfacht. Entwickler können so kritische Momente im Service Worker-Lebenszyklus erkennen und so einfacher darauf reagieren.
  • Um zu verhindern, dass Entwickler häufige Fehler machen, z. B. um einen Service Worker im falschen Bereich zu registrieren.
  • Zum Vereinfachen des Messagings zwischen window und Service Worker-Bereich.

workbox-window importieren und verwenden

Der am häufigsten verwendete Export aus workbox-window ist die Klasse Workbox, die Sie entweder in Node oder aus dem CDN auf einer Webseite importieren können.

Lokales Bundle erstellen

Wenn Ihre Toolchain einen Bundler wie Webpack oder Rollup enthält, können Sie workbox-window lokal bündeln.

Installieren Sie zuerst workbox-window als Produktionsabhängigkeit Ihrer Anwendung:

npm install workbox-window --save

Anschließend können Sie im Anwendungs-JavaScript import die Klasse Workbox aus workbox-window ausführen:

<script type="module">
import {Workbox} from 'workbox-window';

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

  wb.register();
}
</script>

Obwohl workbox-window recht klein ist, könnten Sie sie von der Kernanwendungslogik Ihrer Website mit einem dynamischen import aufteilen. Dadurch kann die Größe des Hauptsets Ihrer Seite reduziert werden:

<script type="module">
if ('serviceWorker' in navigator) {
  const {Workbox} = await import('workbox-window');

  const wb = new Workbox('/sw.js');
  wb.register();
}
</script>

CDN verwenden

Obwohl dies nicht empfohlen wird, ist es einfacher, workbox-window zu verwenden, indem es aus einem CDN importiert wird:

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

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

    wb.register();
  }
</script>

Für das <script>-Element im Beispiel oben wird das Attribut type="module" verwendet. Dies ist erforderlich, wenn Sie im Browser statische import-Anweisungen ohne Build-Schritt verwenden möchten. Alle gängigen Browser, die Service Worker unterstützen, unterstützen auch JavaScript-Module. Dieser Code kann also in jedem Browser bereitgestellt werden, da ältere Browser <script>-Elemente mit dem type-Attributwert "module" ignorieren.

Service Worker registrieren

Die Registrierung eines Service Workers bei workbox-window erfolgt mit der register-Methode der Workbox-Klasse so:

import {Workbox} from 'workbox-window';

const wb = new Workbox('/sw.js');
wb.register();

Es scheint so, als würden Sie einen Service Worker selbst mit navigator.serviceWorker.register registrieren. Workbox.register wartet jedoch bis zum Ereignis window load, bevor der Service Worker registriert wird. Dies ist in Situationen wünschenswert, in denen Precaching beteiligt ist, damit Bandbreitenkonflikte vermieden werden können, die den Seitenstart verzögern könnten.

Kommunikation zwischen window und dem Service Worker-Bereich

Service Worker haben einen eigenen Bereich, der vom window getrennt ist, und haben nur Zugriff auf einen Teil der in window verfügbaren APIs. Es ist jedoch möglich, zwischen window und dem Service Worker zu kommunizieren. workbox-window ermöglicht eine einfachere Kommunikation zwischen den beiden Bereichen mit der Methode messageSW des workbox-window-Moduls.

Workbox verwendet ein bestimmtes Format für Nachrichten ist ein Objekt mit den folgenden Eigenschaften:

  • type ist ein erforderlicher eindeutiger String, der die Nachricht identifiziert. Das Format muss in Großbuchstaben angegeben sein und die Wörter durch Unterstriche trennen (z. B. CACHE_URLS).
  • meta ist ein optionaler String, der den Namen des Workbox-Pakets darstellt, das die Nachricht sendet, und wird normalerweise weggelassen.
  • payload ist ein optionaler Parameter für die Daten, die Sie senden möchten. Es kann sich um einen beliebigen Datentyp handeln.

Im Folgenden finden Sie ein Beispiel für die Funktionsweise von messageSW, beginnend mit dem Code in Ihrem Service Worker:

// sw.js
const SW_VERSION = '1.0.0';

self.addEventListener('message', (event) => {
  if (event.data.type === 'GET_VERSION') {
    event.ports[0].postMessage(SW_VERSION);
  }
});

Fügen Sie dann den folgenden Code in Ihre Webseite ein:

const wb = new Workbox('/sw.js');
wb.register();

const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);

In vielen Fällen kann die Kommunikation zwischen einem Service Worker und dem window nützlich sein. So wird z. B. der Nutzer benachrichtigt, wenn ein Service Worker-Update verfügbar ist. Dieses Rezept beruht auf einer speziellen Hilfsmethode für self.skipWaiting mit dem Namen messageSkipWaiting, die eine Nachricht mit dem type-Wert SKIP_WAITING sendet.