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
.