Utilizzo finestra-casella di lavoro

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 window e 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 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 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.