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
fbclidviene ora ignorato daworkbox-precachingdurante la ricerca di una risposta prememorizzata nella cache per una determinata richiesta. - Il costruttore
PrecacheControllerora 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 metodoaddPlugins()della versione 5) efallbackToNetwork(che sostituisce l'opzione simile passata acreateHandler()e `createHandlerBoundToURL() nella versione 5). - I metodi
install()eactivate()diPrecacheControllerora accettano esattamente un parametro, che deve essere impostato rispettivamente su unInstallEventoActivateEventcorrispondente. - Il metodo
addRoute()è stato rimosso daPrecacheController. Al suo posto, è possibile utilizzare la nuova classePrecacheRouteper creare una route che puoi poi registrare. - Il metodo
precacheAndRoute()è stato rimosso daPrecacheController. (Esiste ancora come metodo statico di supporto esportato dal moduloworkbox-precaching.) È stato rimosso perché è possibile utilizzarePrecacheRoute. - Il metodo
createMatchCalback()è stato rimosso daPrecacheController. In alternativa, è possibile utilizzare il nuovoPrecacheRoute. - Il metodo
createHandler()è stato rimosso daPrecacheController. In alternativa, per gestire le richieste è possibile utilizzare la proprietàstrategydell'oggettoPrecacheController. - L'esportazione statica
createHandler()è già stata rimossa dal moduloworkbox-precaching. Al suo posto, gli sviluppatori devono creare un'istanzaPrecacheControllere utilizzare la relativa proprietàstrategy. - La route registrata con
precacheAndRoute()è ora una route "reale" che utilizza la classeRouterdiworkbox-routingin background. Ciò potrebbe comportare un ordine di valutazione diverso delle route se alterni le chiamate aregisterRoute()eprecacheAndRoute().
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 sonoGET, non è necessario apportare modifiche. - Se hai richieste che non sono
GET(POST,PUTe 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 metodohandle()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 metodohandle()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 attivareskipWaiting(). - 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.