Un modulo Workbox che non ha ancora ottenuto molta copertura in questa documentazione è workbox-window
, ovvero un insieme di moduli destinati a essere eseguiti nella window
. Gli obiettivi di questo modulo sono:
- Per semplificare la registrazione e gli aggiornamenti dei service worker, aiutando gli sviluppatori a identificare i momenti critici del ciclo di vita dei service worker, in modo da poter rispondere più facilmente in quei momenti.
- Per impedire agli sviluppatori di commettere errori comuni, ad esempio la registrazione di un service worker nell'ambito sbagliato.
- Per semplificare la messaggistica tra
window
e l'ambito del service worker.
Importazione e utilizzo di workbox-window
in corso...
L'esportazione che utilizzerai più spesso da workbox-window
è la classe Workbox
, che puoi importare in Node o dalla rete CDN in una pagina web.
Creazione di un bundle locale
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 dell'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
è piuttosto piccolo, potresti suddividerlo dalla logica dell'applicazione principale 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 rete CDN
Sebbene non sia l'approccio consigliato, un modo più semplice per utilizzare workbox-window
consiste nell'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 sopra utilizza l'attributo type="module"
. Questa operazione è necessaria se vuoi utilizzare istruzioni import
statiche nel browser senza un passaggio di build. Tutti i principali browser che supportano i service worker supportano anche i moduli JavaScript, quindi è possibile fornire questo codice a qualsiasi browser, poiché i browser meno recenti ignorano 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
, in questo modo:
import {Workbox} from 'workbox-window';
const wb = new Workbox('/sw.js');
wb.register();
Può sembrare che la registrazione sia uguale alla registrazione di un service worker usando navigator.serviceWorker.register
. Tuttavia, Workbox.register
si occupa di attendere fino all'evento window
load
prima di registrare il service worker. Questo è auspicabile in situazioni in cui è prevista la memorizzazione nella cache, in modo da evitare contese della larghezza di banda che potrebbero ritardare l'avvio della pagina.
Comunicazione tra window
e l'ambito del service worker
I service worker hanno un proprio 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 trattini bassi per separare le parole (ad esempio,CACHE_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 che vuoi inviare. Può essere qualsiasi tipo di dati.
Di seguito è riportato un esempio di come funziona messageSW
, a partire dal codice nel 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);
}
});
E poi il seguente codice nella tua 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 window
può essere utile, ad esempio informare l'utente quando è disponibile un aggiornamento del service worker. Questa ricetta si basa su un metodo helper speciale per self.skipWaiting
chiamato messageSkipWaiting
, che invia un messaggio con un valore type
pari a SKIP_WAITING
.