Korzystanie z okna skrzynki roboczej

Jeden z modułów Workbox, który nie został jeszcze dokładnie omówiony w tej dokumentacji, to workbox-window, czyli zestaw modułów przeznaczonych do uruchamiania w window. Cele tego modułu:

  • Aby uprościć rejestrację i aktualizacje mechanizmów Service Worker, pomagając deweloperom w identyfikowaniu krytycznych momentów cyklu życia tych procesów oraz ułatwia reagowanie w tych momentach.
  • zapobieganie popełnianiu przez deweloperów typowych błędów, takich jak rejestrowanie usługi w nieprawidłowym zakresie;
  • Upraszczanie przesyłania wiadomości między usługą window a usługą robota.

Importowanie i używanie usługi workbox-window

Najczęściej używane jest eksportowanie z workbox-window, czyli klasa Workbox, którą możesz importować w Node.js lub z sieci CDN na stronie internetowej.

Tworzenie lokalnego pakietu

Jeśli Twoja ł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 JavaScripcie aplikacji możesz import klasę 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>

Chociaż workbox-window jest dość mały, możesz oddzielić go od głównej logiki aplikacji witryny, używając 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 CDN

Chociaż nie jest to zalecane podejście, łatwiejszym sposobem na użycie workbox-window jest zaimportowanie go z 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 powyższym przykładzie używa atrybutu type="module". Jest to wymagane, jeśli chcesz używać statycznych instrukcji import w przeglądarce bez wykonywania kroku kompilacji. Wszystkie główne przeglądarki, które obsługują usługi w tle, obsługują też moduły JavaScriptu, więc można przesyłać ten kod do dowolnej przeglądarki, ponieważ starsze przeglądarki ignorują elementy <script> o wartości atrybutu type równej "module".

Rejestrowanie skryptu service worker

Skrypt service worker w workbox-window można zarejestrować za pomocą metody register klasy Workbox w ten sposób:

import {Workbox} from 'workbox-window';

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

Może Ci się wydawać, że różni się to od samodzielnego zarejestrowania skryptu service worker za pomocą navigator.serviceWorker.register. Workbox.register zajmuje się jednak oczekiwaniem na zdarzenie window load przed zarejestrowaniem skryptu service worker. Jest to pożądane w sytuacjach, gdy korzystasz z wstępnego buforowania, aby uniknąć rywalizacji o przepustowość, która może opóźnić wczytywanie strony.

Komunikacja między window a zakresem usługi

Usługa workera ma własny zakres oddzielony od window i ma dostęp tylko do podzbioru interfejsów API dostępnych w window. Możliwa jest jednak komunikacja między window a usługą. workbox-window umożliwia łatwiejszą komunikację między tymi dwoma zakresami za pomocą metody messageSW w module workbox-window.

Workbox używa określonego formatu wiadomości, który jest obiektem z tymi właściwościami:

  • type to wymagany unikalny ciąg znaków identyfikujący wiadomość. Format powinien być pisany wielkimi literami, a słowa powinny być rozdzielane znakami podkreślenia (np. CACHE_URLS).
  • meta to opcjonalny ciąg tekstowy reprezentujący nazwę pakietu Workbox wysyłającego wiadomość. Zwykle jest pomijany.
  • payload to opcjonalny parametr reprezentujący dane, które chcesz wysłać. Może to być dowolny typ danych.

Poniżej przedstawiamy przykład działania funkcji messageSW, zaczynając od kodu w usługach działających w tle:

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

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

Potem następujący 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);

Istnieje wiele sytuacji, w których komunikacja między usługą i window może być przydatna, np. powiadamianie użytkownika o dostępności aktualizacji usługi. Ten przepis korzysta ze specjalnej metody pomocniczej self.skipWaiting o nazwie messageSkipWaiting, która wysyła wiadomość z wartością type równą SKIP_WAITING.