Workbox-Fenster verwenden

Ein Workbox-Modul, das in dieser Dokumentation noch nicht umfassend behandelt wurde, ist workbox-window. Dabei handelt es sich um eine Reihe von Modulen, die in der window ausgeführt werden sollen. In diesem Modul werden folgende Ziele behandelt:

  • Die Registrierung und Aktualisierung von Service Workern wird vereinfacht, indem Entwickler wichtige Momente im Service-Worker-Lebenszyklus erkennen und so leichter darauf reagieren können.
  • Um zu verhindern, dass Entwickler häufige Fehler wie die Registrierung eines Service Workers im falschen Bereich machen.
  • Damit die Kommunikation zwischen window und dem Service Worker-Kontext vereinfacht wird.

workbox-window importieren und verwenden

Der Export, den Sie am häufigsten aus workbox-window verwenden, ist die Workbox-Klasse, 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 in Ihrem Anwendungs-JavaScript die Workbox-Klasse aus workbox-window import:

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

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

  wb.register();
}
</script>

Auch wenn workbox-window recht klein ist, können Sie es mithilfe von dynamischem import von der Hauptanwendungslogik Ihrer Website trennen. Dadurch lässt sich die Größe des Hauptbundles Ihrer Seite reduzieren:

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

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

CDN verwenden

Es ist zwar nicht empfehlenswert, aber Sie können workbox-window auch einfacher aus einem CDN importieren:

<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>

Beachten Sie, dass für das <script>-Element im obigen Beispiel das type="module"-Attribut verwendet wird. 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. Sie können diesen Code also für jeden Browser bereitstellen, 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();

Dies entspricht möglicherweise der Registrierung eines Service Workers über navigator.serviceWorker.register. Workbox.register wartet jedoch bis zum Ereignis window load, bevor der Service Worker registriert wird. Dies ist in Situationen sinnvoll, in denen Precaching erforderlich ist, um Bandbreitenkonflikte zu vermeiden, die den Start der Seite verzögern können.

Kommunikation zwischen dem window- und dem Service Worker-Kontext

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

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

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

Unten sehen 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);

Die Kommunikation zwischen einem Service Worker und dem window kann in vielen Fällen nützlich sein, zum Beispiel die Benachrichtigung des Nutzers, wenn ein Service Worker-Update verfügbar ist. Dieses Rezept verwendet eine spezielle Hilfsmethode für self.skipWaiting mit dem Namen messageSkipWaiting, die eine Nachricht mit dem type-Wert SKIP_WAITING sendet.