Eseguire la migrazione da Workbox v5 a v6

Questa guida si concentra sulle modifiche che provocano un errore introdotte in Workbox v6, con esempi di modifiche da apportare durante l'upgrade da Workbox v5.

Modifiche che provocano un errore

workbox-core

Il metodo skipWaiting() in workbox-core non aggiungerà più un gestore install ed equivale alla semplice chiamata di self.skipWaiting().

D'ora in poi, utilizza self.skipWaiting(), poiché skipWaiting() verrà probabilmente rimosso in Workbox v7.

workbox-precaching

  • I documenti HTML multiorigine per gli URL che corrispondono a un reindirizzamento HTTP non possono più essere utilizzati per soddisfare una richiesta di navigazione con workbox-precaching. Questo scenario è generalmente insolito.
  • Il parametro di query dell'URL fbclid viene ora ignorato da workbox-precaching durante la ricerca di una risposta prememorizzata nella cache per una determinata richiesta.
  • Il costruttore PrecacheController ora accetta come parametro un oggetto con proprietà specifiche, anziché una stringa. Questo oggetto supporta le seguenti proprietà: cacheName (che ha lo stesso scopo della stringa passata al costruttore nella versione 5), plugins (che sostituisce il metodo addPlugins() della versione 5) e fallbackToNetwork (che sostituisce l'opzione simile passata a createHandler() e `createHandlerBoundToURL() nella versione 5).
  • I metodi install() e activate() di PrecacheController ora accettano esattamente un parametro, che deve essere impostato rispettivamente su un InstallEvent o ActivateEvent corrispondente.
  • Il metodo addRoute() è stato rimosso da PrecacheController. Al suo posto, è possibile utilizzare la nuova classe PrecacheRoute per creare una route che puoi poi registrare.
  • Il metodo precacheAndRoute() è stato rimosso da PrecacheController. (Esiste ancora come metodo statico di supporto esportato dal modulo workbox-precaching.) È stato rimosso perché è possibile utilizzare PrecacheRoute.
  • Il metodo createMatchCalback() è stato rimosso da PrecacheController. In alternativa, è possibile utilizzare il nuovo PrecacheRoute.
  • Il metodo createHandler() è stato rimosso da PrecacheController. In alternativa, per gestire le richieste è possibile utilizzare la proprietà strategy dell'oggetto PrecacheController.
  • L'esportazione statica createHandler() è già stata rimossa dal modulo workbox-precaching. Al suo posto, gli sviluppatori devono creare un'istanza PrecacheController e utilizzare la relativa proprietà strategy.
  • La route registrata con precacheAndRoute() è ora una route "reale" che utilizza la classe Router di workbox-routing in background. Ciò potrebbe comportare un ordine di valutazione diverso delle route se alterni le chiamate a registerRoute() e precacheAndRoute().

workbox-routing

Il metodo setDefaultHandler() ora accetta un secondo parametro facoltativo corrispondente al metodo HTTP a cui si applica, con valore predefinito 'GET'.

  • Se utilizzi setDefaultHandler() e tutte le tue richieste sono GET, non è necessario apportare modifiche.
  • Se hai richieste che non sono GET (POST, PUT e così via), setDefaultHandler() non causerà più la corrispondenza di queste richieste.

Configurazione di compilazione

L'opzione mode per le modalità getManifest e injectManifest in workbox-build e workbox-cli non era destinata a essere supportata ed è stata rimossa. Questo non si applica a workbox-webpack-plugin, che supporta mode nel suo plug-in InjectManifest.

Gli strumenti di build richiedono Node.js v10 o versioni successive

Le versioni di Node.js precedenti alla v10 non sono più supportate per workbox-webpack-plugin, workbox-build o workbox-cli. Se utilizzi una versione di Node.js precedente alla v8, aggiorna il runtime a una versione supportata.

Nuovi miglioramenti

workbox-strategies

Workbox v6 introduce un nuovo modo per gli sviluppatori di terze parti di definire le proprie strategie Workbox. In questo modo, gli sviluppatori di terze parti hanno la possibilità di estendere Workbox in modi che soddisfano appieno le loro esigenze.

Nuova classe base Strategy

Nella versione 6, tutte le classi di strategia di Workbox devono estendere la nuova classe base Strategy. Tutte le strategie integrate sono state riscritte per supportare questa funzionalità.

La classe base Strategy è responsabile di due aspetti principali:

  • Richiamare i callback del ciclo di vita del plug-in comuni a tutti i gestori delle strategie (ad esempio quando iniziano, rispondono e terminano).
  • Creare un'istanza "handler" che possa gestire lo stato di ogni singola richiesta gestita da una strategia.

Nuova classe "handler"

In precedenza, i moduli interni chiamavano fetchWrapper e cacheWrapper, che (come suggerisce il nome) racchiudono le varie API di recupero e memorizzazione nella cache con hook nel loro ciclo di vita. Questo è il meccanismo che attualmente consente il funzionamento dei plug-in, ma non è esposto agli sviluppatori.

La nuova classe "handler", StrategyHandler, esporrà questi metodi in modo che le strategie personalizzate possano chiamare fetch() o cacheMatch() e richiamare automaticamente i plug-in aggiunti all'istanza della strategia.

Questa classe consentirebbe inoltre agli sviluppatori di aggiungere i propri callback del ciclo di vita personalizzati, che potrebbero essere specifici per le loro strategie, e funzionerebbero "semplicemente" con l'interfaccia del plug-in esistente.

Nuovo stato del ciclo di vita del plug-in

In Workbox v5, i plug-in sono stateless. Ciò significa che se una richiesta di /index.html attiva sia i callback requestWillFetch che cachedResponseWillBeUsed, questi due callback non hanno modo di comunicare tra loro o anche solo di sapere che sono stati attivati dalla stessa richiesta.

Nella versione 6, a tutti i callback dei plug-in verrà passato anche un nuovo oggetto state. Questo oggetto di stato sarà univoco per questo particolare oggetto plug-in e questa particolare chiamata della strategia (ovvero la chiamata a handle()). Ciò consente agli sviluppatori di scrivere plug-in in cui un callback può eseguire un'azione in modo condizionale in base a ciò che ha fatto un altro callback nello stesso plug-in (ad esempio, calcolare il delta temporale tra l'esecuzione di requestWillFetch e fetchDidSucceed o fetchDidFail).

Nuovi callback del ciclo di vita dei plug-in

Sono stati aggiunti nuovi callback del ciclo di vita dei plug-in per consentire agli sviluppatori di sfruttare appieno lo stato del ciclo di vita dei plug-in:

  • handlerWillStart: viene chiamato prima dell'esecuzione di qualsiasi logica del gestore. Questo callback può essere utilizzato per impostare lo stato iniziale del gestore (ad es. registrare l'ora di inizio).
  • handlerWillRespond: viene chiamato prima che il metodo handle() delle strategie restituisca una risposta. Questo callback può essere utilizzato per modificare la risposta prima di restituirla a un gestore di route o a un'altra logica personalizzata.
  • handlerDidRespond: viene chiamato dopo che il metodo handle() della strategia restituisce una risposta. Questo callback può essere utilizzato per registrare eventuali dettagli finali della risposta, ad esempio dopo le modifiche apportate da altri plug-in.
  • handlerDidComplete: viene chiamato dopo che tutte le promesse di estensione della durata aggiunte all'evento dalla chiamata di questa strategia sono state risolte. Questo callback può essere utilizzato per generare report su tutti i dati che devono attendere il completamento del gestore per essere calcolati (ad es. stato dei successi della cache, latenza della cache, latenza di rete).
  • handlerDidError: viene chiamato se il gestore non è stato in grado di fornire una risposta valida da nessuna origine. Questo callback può essere utilizzato per fornire contenuti di "fallback" in alternativa a un errore di rete.

Gli sviluppatori che implementano le proprie strategie personalizzate non devono preoccuparsi di richiamare questi callback, poiché tutto viene gestito da una nuova classe base Strategy.

Tipi TypeScript più accurati per i gestori

Le definizioni TypeScript per vari metodi di callback sono state normalizzate. Ciò dovrebbe portare a una migliore esperienza per gli sviluppatori che utilizzano TypeScript e scrivono il proprio codice per implementare o chiamare i gestori.

workbox-window

Nuovo metodo messageSkipWaiting()

È stato aggiunto un nuovo metodo, messageSkipWaiting(), al modulo workbox-window per semplificare il processo di attivazione del service worker "in attesa". Questo approccio offre alcuni miglioramenti:

  • Chiama postMessage() con il corpo del messaggio standard di fatto, {type: 'SKIP_WAITING'}, che un service worker generato da Workbox controlla per attivare skipWaiting().
  • Sceglie il service worker "in attesa" corretto a cui inviare questo messaggio, anche se non è lo stesso service worker con cui è stato registrato workbox-window.

Rimozione degli eventi "external" a favore di una proprietà isExternal

Tutti gli eventi "esterni" in workbox-window sono stati rimossi e sostituiti con eventi "normali" con una proprietà isExternal impostata su true. In questo modo, gli sviluppatori che ritengono importante questa distinzione possono comunque rilevarla, mentre gli sviluppatori che non hanno bisogno di saperlo possono ignorare la proprietà.

Formula più pulita "Offri agli utenti la possibilità di ricaricare la pagina"

Grazie a entrambe le modifiche precedenti, la formula "Offrire agli utenti la possibilità di ricaricare la pagina" può essere semplificata:

// v6:
<script type="module">
  import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.0.0-alpha.1/workbox-window.prod.mjs';

  if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');

    const showSkipWaitingPrompt = () => {
      // This assumes a hypothetical createUIPrompt() method with
      // onAccept and onReject callbacks:
      const prompt = createUIPrompt({
        onAccept: () => {
          wb.addEventListener('controlling', () => {
            window.location.reload();
          });

          // This will postMessage() to the waiting service worker.
          wb.messageSkipWaiting();
        },

        onReject: () => {
          prompt.dismiss();
        },
      });
    };

    // Listening for externalwaiting is no longer needed.
    wb.addEventListener('waiting', showSkipWaitingPrompt);
    wb.register();
  }
</script>

workbox-routing

Un nuovo parametro booleano, sameOrigin, viene passato alla funzione matchCallback utilizzata in workbox-routing. È impostato su true se la richiesta riguarda un URL di origine, altrimenti su false.

In questo modo, alcuni boilerplate comuni vengono semplificati:

// In v5:
registerRoute(
  ({url}) =>
    url.origin === self.location.origin && url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'})
);

// In v6:
registerRoute(
  ({sameOrigin, url}) => sameOrigin && url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'})
);

matchOptions in workbox-expiration

Ora puoi impostare matchOptions in workbox-expiration, che verrà poi trasmesso come CacheQueryOptions alla chiamata cache.delete() sottostante. La maggior parte degli sviluppatori non avrà bisogno di farlo.

workbox-precaching

Utilizza workbox-strategies

workbox-precaching è stato riscritto per utilizzare workbox-strategies come base. Ciò non dovrebbe comportare modifiche che provocano un errore e dovrebbe portare a una migliore coerenza a lungo termine nel modo in cui i due moduli accedono alla rete e alla cache.

La pre-memorizzazione nella cache ora elabora le voci una alla volta, non collettivamente

workbox-precaching è stato aggiornato in modo che venga richiesta e memorizzata nella cache una sola voce del manifest di pre-memorizzazione nella cache alla volta, anziché tentare di richiederle e memorizzarle tutte contemporaneamente (lasciando al browser il compito di capire come limitare la frequenza).

In questo modo, dovrebbero ridursi la probabilità di errori net::ERR_INSUFFICIENT_RESOURCES durante il precaching e la contesa della larghezza di banda tra il precaching e le richieste simultanee effettuate dall'app web.

PrecacheFallbackPlugin consente un fallback offline più semplice

workbox-precaching ora include un PrecacheFallbackPlugin, che implementa il nuovo metodo del ciclo di vita handlerDidError aggiunto nella versione 6.

In questo modo è facile specificare un URL prememorizzato nella cache come "fallback" per una determinata strategia quando una risposta non sarebbe altrimenti disponibile. Il plug-in si occuperà di creare correttamente la chiave cache corretta per l'URL prememorizzato nella cache, incluso l'eventuale parametro di revisione necessario.

Ecco un esempio di utilizzo per rispondere con un /offline.html pre-memorizzato nella cache quando la strategia NetworkOnly non può generare una risposta per una richiesta di navigazione, in altre parole, per visualizzare una pagina HTML offline personalizzata:

import {PrecacheFallbackPlugin, precacheAndRoute} from 'workbox-precaching';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

// Ensure that /offline.html is part of your precache manifest!
precacheAndRoute(self.__WB_MANIFEST);

registerRoute(
  ({request}) => request.mode === 'navigate',
  new NetworkOnly({
    plugins: [
      new PrecacheFallbackPlugin({
        fallbackURL: '/offline.html',
      }),
    ],
  })
);

precacheFallback nella memorizzazione nella cache di runtime

Se utilizzi generateSW per creare un service worker anziché scriverlo manualmente, puoi utilizzare la nuova opzione di configurazione precacheFallback in runtimeCaching per ottenere lo stesso risultato:

{
  // ... other generateSW config options...
  runtimeCaching: [{
    urlPattern: ({request}) => request.mode === 'navigate',
    handler: 'NetworkOnly',
    options: {
      precacheFallback: {
        // This URL needs to be included in your precache manifest.
        fallbackURL: '/offline.html',
      },
    },
  }],
}

Risorse di assistenza

Prevediamo che la maggior parte delle migrazioni sarà semplice. Se riscontri problemi non trattati in questa guida, comunicacelo aprendo un problema su GitHub.