Korzystanie z okna skrzynki roboczej

Jeden z modułów Workbox, który nie jest jeszcze obszerny w tej dokumentacji, to workbox-window. Jest to zestaw modułów przeznaczonych do uruchomienia w window. Cele tego modułu:

  • Aby uprościć rejestrację i aktualizowanie skryptu service worker przez deweloperów, którzy mogą identyfikować kluczowe momenty cyklu życia mechanizmów Service Worker i reagować na nie.
  • Aby uniemożliwić deweloperom popełnianie typowych błędów, na przykład zarejestrowanie skryptu service worker w niewłaściwym zakresie.
  • Aby uprościć przesyłanie wiadomości między window a zakresem skryptu service worker.

Importowanie i używanie: workbox-window

Eksportu, którego najczęściej używasz z workbox-window, jest klasa Workbox, którą możesz zaimportować w węźle lub z CDN na stronie internetowej.

Tworzenie pakietu lokalnego

Jeśli łańcuch narzędzi zawiera narzędzie do tworzenia pakietów, takie jak webpack lub Rollup, możesz utworzyć pakiet workbox-window lokalnie.

Najpierw zainstaluj workbox-window jako zależność produkcyjną aplikacji:

npm install workbox-window --save

Następnie, w swoim kodzie JavaScript aplikacji, możesz import użyć klasy Workbox z workbox-window:

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

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

  wb.register();
}
</script>

workbox-window jest dosyć mały, ale możesz go oddzielić od głównej logiki aplikacji w witrynie za pomocą dynamicznego import, co może zmniejszyć rozmiar głównego pakietu strony:

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

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

Korzystanie z sieci CDN

Chociaż nie jest to zalecane, łatwiejszym sposobem korzystania z interfejsu workbox-window jest zaimportowanie go z sieci CDN:

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

Zwróć uwagę, że element <script> w tym przykładzie korzysta z atrybutu type="module". Jest to wymagane, jeśli chcesz używać w przeglądarce statycznych instrukcji import bez kroku kompilacji. Wszystkie popularne przeglądarki, które obsługują mechanizmy Service Worker, obsługują też moduły JavaScript, więc ten kod można przesyłać do dowolnej przeglądarki, ponieważ starsze przeglądarki ignorują elementy <script> o atrybucie type o wartości "module".

Rejestrowanie skryptu service worker

Skrypt service worker można zarejestrować w elemencie workbox-window przy użyciu metody register klasy Workbox w ten sposób:

import {Workbox} from 'workbox-window';

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

Może się to wydawać tak samo jak samodzielne zarejestrowanie skryptu service worker za pomocą navigator.serviceWorker.register. Workbox.register umożliwia jednak oczekiwanie na zdarzenie window load przed zarejestrowaniem skryptu service worker. Jest to zalecane w sytuacjach, gdy wymagane jest wstępne wczytywanie, dzięki czemu można uniknąć rywalizacji o przepustowość, która może opóźniać uruchamianie strony.

Komunikacja między zakresem window a zakresem skryptu service worker

Skrypty service worker mają własny zakres inny niż typ window i mają dostęp tylko do podzbioru interfejsów API w window. Jest jednak możliwe komunikowanie się między skryptem window a skryptem service worker. workbox-window umożliwia łatwiejszą komunikację między 2 zakresami dzięki metodzie messageSW modułu workbox-window.

Skrzynka robocza korzysta z określonego formatu wiadomości, czyli obiektu o następujących właściwościach:

  • type to wymagany unikalny ciąg znaków identyfikujący wiadomość. Format powinien być zapisany wielkimi literami, a słowa rozdzielać podkreśleniami (np. CACHE_URLS).
  • meta to opcjonalny ciąg znaków reprezentujący nazwę pakietu skrzynki roboczej, z którego wysłano wiadomość. Zazwyczaj jest pomijany.
  • payload to opcjonalny parametr reprezentujący dane, które chcesz wysyłać. Może to być dowolny typ danych.

Poniżej znajduje się przykład działania narzędzia messageSW, które rozpoczyna się od kodu w skrypcie 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);
  }
});

Następnie ten kod na stronie internetowej:

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

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

W wielu przypadkach komunikacja między skryptem service worker a platformą window może być przydatna, na przykład powiadomienie użytkownika o dostępnej aktualizacji tego skryptu. Ten przepis korzysta ze specjalnej metody pomocniczej self.skipWaiting o nazwie messageSkipWaiting, która wysyła komunikat z wartością type równą SKIP_WAITING.