Questa guida è incentrata sull'interruzione delle modifiche introdotte in Workbox v5, con esempi di quali modifiche dovresti apportare quando esegui l'upgrade da Workbox v4.
Modifiche che provocano un errore
Classi plug-in rinominate
Diversi pacchetti Workbox 4 includevano classi denominate Plugin
. Nella versione 5, queste classi sono state rinominate seguendo l'identificatore del pacchetto di pattern + Plugin
:
BackgroundSyncPlugin
BroadcastUpdatePlugin
CacheableResponsePlugin
ExpirationPlugin
RangeRequestsPlugin
Questa ridenominazione si applica se utilizzi le classi tramite le importazioni dei moduli o tramite gli spazi dei nomi workbox.*
.
Punto di sostituzione predefinito del file manifest di pre-cache
In precedenza, quando utilizzavi uno degli strumenti di compilazione in modalità "inserisci manifest", veniva controllata la presenza di precacheAndRoute([])
nel file del tuo worker di servizio di origine, con l'array vuoto []
utilizzato come segnaposto per il punto in cui è stato inserito il manifest precache.
In Workbox v5, la logica di sostituzione è cambiata e ora viene utilizzato self.__WB_MANIFEST
per impostazione predefinita come punto di inserimento.
// v4:
precacheAndRoute([]);
// v5:
precacheAndRoute(self.__WB_MANIFEST);
Come descritto in questa discussione, riteniamo che questa modifica offra un'esperienza più semplice e, al contempo, che offra agli sviluppatori un maggiore controllo sulle modalità di utilizzo del manifest inserito all'interno del codice del service worker personalizzato. Se necessario, puoi modificare questa stringa di sostituzione tramite l'opzione di configurazione injectionPoint
.
Modifiche al percorso di navigazione
Due opzioni precedentemente supportate per i percorsi di navigazione, blacklist
e whitelist
, sono state rinominate denylist
e allowlist
.
In precedenza workbox-routing
supportava un metodo, registerNavigationRoute()
, che, in base alle necessità, ha fatto due cose:
- È stato rilevato se un determinato evento
fetch
aveva o meno unmode
di'navigate'
. - In tal caso, ha risposto alla richiesta utilizzando i contenuti di un URL precedentemente memorizzato nella cache, indipendentemente dall'URL visitato.
Si tratta di un pattern comune da utilizzare durante l'implementazione dell'architettura della shell dell'app.
Il secondo passaggio, la generazione di una risposta tramite lettura dalla cache, ricade al di fuori di quelle che consideriamo responsabilità di workbox-routing
. La consideriamo invece una funzionalità che dovrebbe far parte di workbox-precaching
tramite un nuovo metodo, createHandlerBoundToURL()
. Questo nuovo metodo può funzionare insieme alla classe NavigationRoute
esistente in workbox-routing
per ottenere la stessa logica.
Se utilizzi l'opzione navigateFallback
in uno degli strumenti di creazione "Genera SW" , il passaggio avverrà automaticamente. Se in precedenza hai configurato le opzioni navigateFallbackBlacklist
o navigateFallbackWhitelist
, modificale rispettivamente in navigateFallbackDenylist
o navigateFallbackAllowlist
.
Se utilizzi il comando "inject manifest" (Inserisci manifest) o semplicemente scrivendo il service worker personalmente e il service worker di Workbox v4 chiama direttamente registerNavigationRoute()
, quindi dovrai modificare il codice per ottenere il comportamento equivalente.
// v4:
import {getCacheKeyForURL} from 'workbox-precaching';
import {registerNavigationRoute} from 'workbox-routing';
const appShellCacheKey = getCacheKeyForURL('/app-shell.html');
registerNavigationRoute(appShellCacheKey, {
whitelist: [...],
blacklist: [...],
});
// v5:
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';
const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
allowlist: [...],
denylist: [...],
});
registerRoute(navigationRoute);
Non è più necessario chiamare getCacheKeyForURL()
, perché createHandlerBoundToURL()
si occuperà di tutto.
Rimozione di makeRequest() dalle strategie workbox
La chiamata a makeRequest()
è per lo più equivalente alla chiamata a handle()
in una delle classi workbox-strategy
. Le differenze tra i due metodi erano così lievi che non aveva senso mantenerli entrambi. Gli sviluppatori che hanno chiamato makeRequest()
dovrebbero essere in grado di passare all'utilizzo di handle()
senza ulteriori modifiche:
// v4:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.makeRequest({event, request});
// v5:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.handle({event, request});
Nella versione 5, handle()
considera request
come parametro obbligatorio e non utilizza più event.request
. Assicurati di inviare una richiesta valida quando chiami il numero handle()
.
workbox-broadcast-update utilizza sempre postMessage()
Nella versione 4, la libreria workbox-broadcast-update
utilizzava per impostazione predefinita l'API Broadcast Channel per l'invio di messaggi quando era supportata e utilizzava postMessage()
solo quando Broadcast Channel non era supportato.
Ci siamo resi conto che dover ascoltare due potenziali fonti dei messaggi in arrivo rendeva eccessivamente complicata la scrittura di codice lato client. Inoltre, su alcuni browser, le chiamate postMessage()
del service worker inviate alle pagine client vengono automaticamente memorizzate nel buffer finché non viene configurato un listener di eventi message
. Non è previsto il buffering con l'API Broadcast Channel e i messaggi trasmessi vengono semplicemente eliminati se inviati prima che una pagina del client sia pronta a riceverli.
Per questo motivo, abbiamo modificato workbox-broadcast-update
in modo che utilizzi sempre postMessage()
nella versione 5. I messaggi vengono inviati uno alla volta a tutte le pagine del client nell'ambito dell'attuale worker di servizio.
Per soddisfare questo nuovo comportamento, puoi rimuovere l'eventuale codice presente nelle pagine client che ha creato istanze BroadcastChannel
e impostare invece un listener di eventi message
su navigator.serviceWorker
:
// v4:
const updatesChannel = new BroadcastChannel('api-updates');
updatesChannel.addEventListener('message', event => {
const {cacheName, updatedUrl} = event.data.payload;
// ... your code here ...
});
// v5:
// This listener should be added as early as possible in your page's lifespan
// to ensure that messages are properly buffered.
navigator.serviceWorker.addEventListener('message', event => {
// Optional: ensure the message came from workbox-broadcast-update
if (event.meta === 'workbox-broadcast-update') {
const {cacheName, updatedUrl} = event.data.payload;
// ... your code here ...
}
});
Non dovrebbe essere necessario apportare alcuna modifica agli utenti di workbox-window
, poiché la sua logica interna è stata aggiornata per rimanere in ascolto delle chiamate postMessage()
.
Gli strumenti di compilazione richiedono Node.js 8 o versioni successive
Le versioni di Node.js precedenti alla v8 non sono più supportate per workbox-webpack-plugin
, workbox-build
o workbox-cli
. Se utilizzi una versione di Node.js precedente alla 8, aggiorna il runtime a una versione supportata.
workbox-webpack-plugin richiede webpack 4 o versioni successive
Se utilizzi workbox-webpack-plugin
, aggiorna la configurazione del webpack in modo da utilizzare almeno la versione v4.
Revisione dell'opzione dello strumento di compilazione
Diversi parametri di configurazione workbox-build
, workbox-cli
e workbox-webpack-plugin
non sono più supportati. Ad esempio, generateSW
creerà sempre per te un bundle di runtime Workbox locale, quindi l'opzione importWorkboxFrom
non ha più senso.
Consulta la documentazione dello strumento pertinente per l'elenco delle opzioni supportate.
Rimozione di generateSWString da workbox-build
La modalità generateSWString
è stata rimossa da workbox-build
. Ci aspettiamo che l'impatto di questa funzionalità sia minimo, dato che è stato utilizzato principalmente internamente da workbox-webpack-plugin
.
Modifiche facoltative
Utilizzo delle importazioni di moduli
Sebbene questa modifica sia a) facoltativa e b) tecnicamente possibile quando si utilizza Workbox v4, il cambiamento più grande che prevediamo durante il passaggio alla versione 5 è un modello in cui crei il tuo service worker in bundle importando i moduli di Workbox. Questo approccio è un'alternativa alla chiamata di importScripts('/path/to/workbox-sw.js')
nella parte superiore del tuo worker di servizio e all'utilizzo di Workbox tramite lo spazio dei nomi workbox.*
.
Se utilizzi uno degli strumenti di compilazione (workbox-webpack-plugin
, workbox-build
, workbox-cli
) in modalità "Genera SW", questa modifica verrà eseguita automaticamente. Tutti questi strumenti produrranno un bundle locale e personalizzato del runtime di Workbox insieme al codice effettivo necessario per implementare la logica del tuo worker di servizio. In questo scenario, non sussiste più alcuna dipendenza da workbox-sw
o dalla copia CDN di Workbox. A seconda del valore della configurazione inlineWorkboxRuntime
, il runtime di Workbox verrà suddiviso in un file separato da implementare insieme al tuo worker di servizio (se impostato su false
, il valore predefinito) o incluso in linea con la logica del worker di servizio (se impostato su true
).
Se utilizzi gli strumenti di creazione in un file manifest "inject" o se non utilizzi affatto gli strumenti di creazione di Workbox, puoi scoprire di più sulla creazione di un bundle di runtime Workbox nella guida esistente Using Bundlers (webpack/Rollup) with Workbox.
La documentazione e gli esempi per la versione 5 sono scritti presupponendo la sintassi delle importazioni del modulo, anche se lo spazio dei nomi workbox.*
continuerà a essere supportato nella versione 5 di Workbox.
Lettura delle risposte prememorizzate nella cache
Alcuni sviluppatori devono leggere le risposte prememorizzate nella cache direttamente dalla cache, anziché utilizzarle implicitamente tramite il metodo precacheAndRoute()
. Un pattern comune nella versione 4 consiste nell'ottenere prima la chiave della cache specifica per la versione corrente di una risorsa pre-cache, quindi nell'inviare questa chiave insieme al nome della cache della pre-cache a caches.match()
per ottenere Response
.
Per semplificare questa procedura, workbox-precaching
nella versione 5 supporta un nuovo metodo equivalente, matchPrecache()
:
// v4:
import {cacheNames} from 'workbox-core';
import {getCacheKeyForURL} from 'workbox-precaching';
const cachedResponse = await caches.match(
getCacheKeyForURL(`/somethingPrecached`),
{
cacheName: cacheNames.precache,
}
);
// v5:
import {matchPrecache} from 'workbox-precaching';
const cachedResponse = await matchPrecache(`/somethingPrecached`);
Adozione TypeScript
Nella versione 5, le librerie di runtime di Workbox sono scritte in TypeScript. Continueremo a pubblicare moduli e bundle JavaScript sottoposti a transpile per supportare gli sviluppatori che non hanno adottato TypeScript, ma se utilizzi TypeScript, dovresti trarre vantaggio da informazioni sul tipo accurate e sempre aggiornate direttamente dal progetto Workbox.
Esempio di migrazione
Questo commit illustra una migrazione piuttosto complessa, con commenti in linea. Usa la funzionalità di aggregazione per includere runtime della casella di lavoro personalizzata nel service worker finale anziché caricare il runtime dalla CDN.
Anche se non sono incluse tutte le modifiche che provocano un errore, di seguito vengono riportati il prima e il dopo dell'upgrade di un file del service worker dalla versione 4 alla 5, inclusa la possibilità di passare a TypeScript.
Risorse di assistenza
Prevediamo che la maggior parte delle migrazioni sia semplice. Se riscontri problemi non trattati in questa guida, comunicacelo aprendo un problema su GitHub.