Un modulo Workbox che non è ancora stato trattato in questa documentazione è workbox-window, un insieme di moduli destinati a essere eseguiti in window. Gli obiettivi di questo modulo sono:
- Per semplificare la registrazione e gli aggiornamenti dei worker di servizio aiutando gli sviluppatori a identificare i momenti critici del ciclo di vita dei worker di servizio, facilitando la risposta in quei momenti.
- Per evitare che gli sviluppatori commettano errori comuni, ad esempio la registrazione di un service worker nell'ambito sbagliato.
- Per semplificare la messaggistica tra
windowe l'ambito del worker del servizio.
Importazione e utilizzo di workbox-window
L'esportazione che utilizzerai più spesso da workbox-window è la classe Workbox, che puoi importare in Node o dalla CDN in una pagina web.
Creazione di un bundle locale in corso...
Se la tua toolchain include un bundler come webpack o Rollup, puoi raggruppare workbox-window localmente.
Innanzitutto, installa workbox-window come dipendenza di produzione della tua applicazione:
npm install workbox-window --save
Quindi, nel codice JavaScript della tua applicazione, puoi import la classe Workbox da workbox-window:
<script type="module">
import {Workbox} from 'workbox-window';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
Anche se workbox-window è abbastanza piccolo, potresti suddividerlo dalla logica principale dell'applicazione del tuo sito web utilizzando import dinamico, che può ridurre le dimensioni del bundle principale della tua pagina:
<script type="module">
if ('serviceWorker' in navigator) {
const {Workbox} = await import('workbox-window');
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
Utilizzo della CDN
Sebbene non sia l'approccio consigliato, un modo più semplice per utilizzare workbox-window è importarlo da una 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>
Noterai che l'elemento <script> nell'esempio riportato sopra utilizza l'attributo type="module". Questo è necessario se vuoi utilizzare istruzioni import statiche nel browser senza un passaggio di compilazione. Tutti i principali browser che supportano i service worker supportano anche i moduli JavaScript, quindi puoi pubblicare questo codice su qualsiasi browser, poiché i browser meno recenti ignoreranno gli elementi <script> con un valore dell'attributo type pari a "module".
Registrazione di un service worker
La registrazione di un service worker con workbox-window viene eseguita con il metodo register della classe Workbox nel seguente modo:
import {Workbox} from 'workbox-window';
const wb = new Workbox('/sw.js');
wb.register();
Potrebbe sembrare che ciò sia uguale alla registrazione di un service worker utilizzando navigator.serviceWorker.register. Tuttavia, Workbox.register attende l'evento window load prima di registrare il service worker. Ciò è auspicabile nelle situazioni in cui è coinvolta la pre-memorizzazione nella cache, in modo da evitare il conflitto di larghezza di banda che può ritardare l'avvio della pagina.
Comunicazione tra window e l'ambito del service worker
I Service worker hanno un ambito separato da window e hanno accesso solo a un sottoinsieme delle API disponibili in window. Tuttavia, è possibile comunicare tra window e il service worker. workbox-window facilita la comunicazione tra i due ambiti con il metodo messageSW del modulo workbox-window.
Workbox utilizza un formato specifico per i messaggi è un oggetto con le seguenti proprietà:
typeè una stringa univoca obbligatoria che identifica il messaggio. Il formato deve essere in maiuscolo con i trattini bassi che separano le parole (ad esempioCACHE_URLS).metaè una stringa facoltativa che rappresenta il nome del pacchetto Workbox che invia il messaggio e di solito viene omessa.payloadè un parametro facoltativo che rappresenta i dati da inviare. Può essere di qualsiasi tipo di dati.
Di seguito è riportato un esempio di come funziona messageSW, a partire dal codice nel tuo 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);
}
});
Quindi, il seguente codice nella pagina web:
const wb = new Workbox('/sw.js');
wb.register();
const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);
Esistono molti casi in cui la comunicazione tra un service worker e il window può essere utile, ad esempio per avvertire l'utente quando è disponibile un aggiornamento del service worker. Questa ricetta si basa su un metodo di assistenza speciale per self.skipWaiting chiamato messageSkipWaiting, che invia un messaggio con un valore type di SKIP_WAITING.