Eseguire la migrazione da Workbox v2 a v3

Questa guida si concentra sulle modifiche che provocano un errore introdotte in Workbox v3, con esempi delle modifiche che dovrebbero essere apportate quando esegui l'upgrade da una configurazione di Workbox v2.

Se attualmente stai utilizzando la combinazione legacy sw-precache/sw-toolbox e vorresti passare a Workbox per la prima volta, ecco una guida alla migrazione diversa che ti sarà utile.

Sfondo v3

La versione v3 di Workbox rappresenta un refactoring significativo del codebase esistente. Gli obiettivi generali sono:

  • Riduci al minimo le dimensioni della casella di lavoro. La quantità di codice di runtime del service worker che è stato scaricato ed eseguito è stata ridotta. Anziché attivare per tutti un bundle monolitico, verrà importato solo il codice per le funzionalità specifiche che stai utilizzando durante il runtime.
  • Workbox ha una CDN. Forniamo un hosting CDN basato su Google Cloud Storage e completamente supportato come opzione canonica per l'accesso alle librerie di runtime di Workbox, rendendo più facile l'utilizzo con Workbox.
  • Debug e log migliori. L'esperienza di debug e logging è stata notevolmente migliorata. I log di debug sono abilitati per impostazione predefinita ogni volta che Workbox viene utilizzato da un'origine localhost e tutti i log e le asserzioni vengono rimossi dalle build di produzione. Esempio di logging di debug offerto da Workbox v3.
  • Plug-in webpack migliorato. workbox-webpack-plugin si integra maggiormente con il processo di compilazione di Webpack, consentendo un caso d'uso senza configurazione in cui vuoi pre-memorizzare nella cache tutti gli asset nella pipeline di build.

Il raggiungimento di questi obiettivi e la pulizia di alcuni aspetti dell'interfaccia precedente che sembravano imbarazzanti o portavano a anti-pattern, richiedevano l'introduzione di una serie di modifiche che provocano un errore nella release v3.

Modifiche che provocano un errore

Configurazione build

Le modifiche che seguono influiscono sul comportamento di tutti i nostri strumenti di creazione (workbox-build, workbox-cli, workbox-webpack-plugin), che condividono un insieme comune di opzioni di configurazione.

  • Il nome del gestore 'fastest' era precedentemente valido e considerato un alias per 'staleWhileRevalidate' durante la configurazione di runtimeCaching. Non è più valido e gli sviluppatori dovrebbero passare all'utilizzo diretto di 'staleWhileRevalidate'.
  • Sono stati aggiornati diversi nomi di proprietà runtimeCaching.options ed è attiva un'ulteriore convalida dei parametri, a causa del quale una build non riesce se viene utilizzata una configurazione non valida. Consulta la documentazione per runtimeCaching per l'elenco delle opzioni attualmente supportate.

casella di lavoro-sincronizzazione-in-sfondo

  • Il parametro di configurazione maxRetentionTime viene ora interpretato come un numero di minuti, anziché un numero di millisecondi.
  • Ora è disponibile una stringa obbligatoria, che rappresenta il nome della coda, che deve essere trasmessa come primo parametro durante la creazione della classe Plug-in o autonoma. In precedenza è stata trasmessa come proprietà delle opzioni. Consulta la documentazione per la piattaforma API aggiornata.

workbox-broadcast-cache-update

  • Ora è disponibile una stringa obbligatoria, che rappresenta il nome del canale, che deve essere trasmessa come primo parametro durante la creazione della classe Plug-in o autonoma.

Ad esempio, nella v2 devi inizializzare la classe Plugin nel seguente modo:

new workbox.broadcastCacheUpdate.BroadcastCacheUpdatePlugin({
  channelName: 'cache-updates',
  headersToCheck: ['etag'],
});

L'utilizzo equivalente nella versione 3 è:

new workbox.broadcastUpdate.Plugin('cache-updates', {headersToCheck: ['etag']});

Consulta la documentazione per la piattaforma API aggiornata.

build-workbox

  • Per impostazione predefinita, la corrispondenza del pattern glob verrà ora eseguita con le opzioni follow: true (che seguiranno i link simbolici) e strict: true (che tollera meno gli errori "insoliti"). Puoi disattivarne una e tornare al comportamento precedente impostando globFollow: false e/o globStrict: false nella configurazione della build.
  • Tutte le funzioni in workbox-build restituiscono una proprietà aggiuntiva, warnings, nelle risposte che restituiscono. Alcuni scenari che erano stati trattati come errori irreversibili nella versione v2 sono ora consentiti, ma segnalati tramite warnings, che è un array di stringhe.

Nella v2, potresti chiamare generateSW nel seguente modo:

const workboxBuild = require('workbox-build');

workboxBuild.generateSW({...})
  .then(({count, size}) => console.log(`Precached ${count} files, totaling ${size} bytes.`))
  .catch((error) => console.error(`Something went wrong: ${error}`));

Anche se puoi utilizzare lo stesso codice nella versione 3, è consigliabile verificare la presenza di eventuali warnings e registrarli:

const workboxBuild = require('workbox-build');

workboxBuild.generateSW({...})
  .then(({count, size, warnings}) => {
    for (const warning of warnings) {
      console.warn(warning);
    }
    console.log(`Precached ${count} files, totalling ${size} bytes.`);
  })
  .catch((error) => console.error(`Something went wrong: ${error}`));
  • Gli sviluppatori che hanno scritto le proprie funzioni ManifestTransform personalizzate nella versione v2 devono restituire l'array manifest in un oggetto (ad esempio, al posto di return manifestArray; dovresti usare return {manifest: manifestArray};).mIn questo modo il plug-in può includere una proprietà warnings facoltativa, che dovrebbe essere un array di stringhe contenenti informazioni di avviso non irreversibili.

Se stavi scrivendo una ManifestTransform personalizzata nella v2, codice come:

const cdnTransform = manifestEntries => {
  return manifestEntries.map(entry => {
    const cdnOrigin = 'https://example.com';
    if (entry.url.startsWith('/assets/')) {
      entry.url = cdnOrigin + entry.url;
    }
    return entry;
  });
};

ha un equivalente v3 di:

const cdnTransform = manifestEntries => {
  const manifest = manifestEntries.map(entry => {
    const cdnOrigin = 'https://example.com';
    if (entry.url.startsWith('/assets/')) {
      entry.url = cdnOrigin + entry.url;
    }
    return entry;
  });
  return {manifest, warnings: []};
};
  • La funzione getFileManifestEntries() è stata rinominata in getManifest() e la promessa restituita ora include informazioni aggiuntive relative agli URL prememorizzati nella cache.

Usa il codice seguente nella v2:

const manifestEntries = await workboxBuild.getFileManifestEntries({...});

può essere riscritto nella versione 3 come segue:

const {manifestEntries, count, size, warnings} = await workboxBuild.getManifest({...});

// Use manifestEntries like before.
// Optionally, log the new info returned in count, size, warnings.
  • La funzione generateFileManifest() è stata rimossa. Consigliamo agli sviluppatori di chiamare getManifest() e utilizzare la sua risposta per scrivere dati su disco nel formato appropriato.

casella di lavoro-scadenza-cache

  • L'API dei plug-in è rimasta invariata, ed è la modalità che verrà utilizzata dalla maggior parte degli sviluppatori. Tuttavia, sono state apportate modifiche significative all'API che interessano gli sviluppatori che la utilizzano come classe autonoma. Consulta la documentazione per la piattaforma API aggiornata.

workbox-cli

Gli sviluppatori possono eseguire l'interfaccia a riga di comando con il flag --help per un set completo di parametri supportati.

  • Il supporto dell'alias workbox-cli per lo script binario è stato rimosso. Ora è possibile accedere al programma binario soltanto come workbox.
  • I comandi v2 generate:sw e inject:manifest sono stati rinominati generateSW e injectManifest nella versione 3.
  • Nella v2, si presumeva che il file di configurazione predefinito (utilizzato quando non ne era stato fornito esplicitamente uno) fosse workbox-cli-config.js nella directory corrente. Nella versione 3, è workbox-config.js.

Nel loro insieme, ciò significa che nella versione 2:

$ workbox inject:manifest

eseguirebbe il processo di compilazione "inject manifest", utilizzando una configurazione letta da workbox-cli-config.js e nella v3:

$ workbox injectManifest

farà lo stesso, ma leggerà la configurazione da workbox-config.js.

pre-memorizzazione nella cache di lavoro

  • In precedenza, il metodo precache() ha eseguito sia le modifiche alla cache sia l'impostazione del routing per la gestione delle voci memorizzate nella cache. Ora, precache() modifica solo le voci della cache ed è stato esposto un nuovo metodo, addRoute(), per registrare una route per fornire le risposte memorizzate nella cache. Gli sviluppatori che desiderano la precedente funzionalità 2-in-1 possono passare alla chiamata a precacheAndRoute().
  • Diverse opzioni che prima erano configurate tramite il costruttore WorkboxSW vengono ora trasferite come parametro options in workbox.precaching.precacheAndRoute([...], options). Le impostazioni predefinite per queste opzioni, se non configurate, sono elencate nella documentazione di riferimento.
  • Per impostazione predefinita, gli URL privi di estensioni di file vengono automaticamente controllati per individuare corrispondenze con una voce della cache contenente l'estensione .html. Ad esempio, se viene effettuata una richiesta per /path/to/index (che non è prememorizzata nella cache) ed è presente una voce prememorizzata nella cache per /path/to/index.html, verrà utilizzata questa voce. Gli sviluppatori possono disattivare questo nuovo comportamento impostando {cleanUrls: false} quando passano le opzioni in workbox.precaching.precacheAndRoute().
  • workbox-broadcast-update non verrà più configurato automaticamente per annunciare gli aggiornamenti della cache per gli asset pre-memorizzazione nella cache.

Il seguente codice nella v2:

const workboxSW = new self.WorkboxSW({
  directoryIndex: 'index.html',
  ignoreUrlParametersMatching: [/^utm_/],
  precacheChannelName: 'precache-updates',
});
workboxSW.precache([...]);

ha un equivalente v3 di:

workbox.precaching.addPlugins([
    new workbox.broadcastUpdate.Plugin('precache-updates')
]);

workbox.precaching.precacheAndRoute([...], {
  cleanUrls: false,
  directoryIndex: 'index.html',
  ignoreUrlParametersMatching: [/^utm_/],
});

routing-workbox

  • Gli sviluppatori che in precedenza utilizzavano workbox-routing tramite lo spazio dei nomi workbox.router.* di un oggetto WorkboxSW devono passare al nuovo spazio dei nomi, workbox.routing.*.
  • I percorsi vengono ora valutati secondo l'ordine delle vittorie registrate per la prima volta. Questo è l'ordine opposto della valutazione Route che è stata utilizzata nella versione 2, in cui viene data la precedenza all'ultimo Route registrato.
  • La classe ExpressRoute e il supporto per i caratteri jolly "Stile Express" sono stati rimossi. In questo modo si riducono notevolmente le dimensioni di workbox-routing. Le stringhe utilizzate come primo parametro di workbox.routing.registerRoute() verranno ora trattate come corrispondenze esatte. Le corrispondenze con caratteri jolly o parziali devono essere gestite dagli elementi RegExp; l'utilizzo di qualsiasi RegExp che corrisponda a una parte o a tutto l'URL della richiesta può attivare una route.
  • Il metodo helper addFetchListener() della classe Router è stato rimosso. Gli sviluppatori possono aggiungere esplicitamente il proprio gestore fetch oppure utilizzare l'interfaccia fornita da workbox.routing, che creerà implicitamente un gestore fetch per loro.
  • I metodi registerRoutes() e unregisterRoutes() sono stati rimossi. Le versioni di questi metodi che operano su un singolo Route non sono state modificate e gli sviluppatori che devono registrare o annullare la registrazione di più percorsi contemporaneamente dovrebbero effettuare una serie di chiamate a registerRoute() o unregisterRoute().

Il seguente codice nella v2:

const workboxSW = new self.WorkboxSW();

workboxSW.router.registerRoute(
  '/path/with/.*/wildcard/',
  workboxSW.strategies.staleWhileRevalidate()
);

workboxSW.router.registerRoute(
  new RegExp('^https://example.com/'),
  workboxSW.strategies.networkFirst()
);

ha un equivalente v3 di:

workbox.routing.registerRoute(
  new RegExp('^https://example.com/'),
  workbox.strategies.networkFirst()
);

workbox.routing.registerRoute(
  new RegExp('^/path/with/.*/wildcard'),
  workbox.strategies.staleWhileRevalidate()
);

strategie di workbox (precedentemente note come workbox-runtime-memorizzazione nella cache)

  • Il modulo workbox-runtime-caching è ora ufficialmente noto come workbox-strategies ed è stato pubblicato il giorno npm con il nuovo nome.
  • L'utilizzo della scadenza della cache in una strategia senza specificare anche un nome cache non è più valido. Nella versione 2 è stato possibile:
workboxSW.strategies.staleWhileRevalidate({
  cacheExpiration: {maxEntries: 50},
});

Questo causerebbe la scadenza di voci nella cache predefinita, il che non è previsto. Nella v3, il nome della cache è obbligatorio:

workboxSW.strategies.staleWhileRevalidate({
  cacheName: 'my-cache',
  plugins: [new workbox.expiration.Plugin({maxEntries: 50})],
});
  • Il metodo del ciclo di vita di cacheWillMatch è stato rinominato in cachedResponseWillBeUsed. Questa modifica non dovrebbe essere visibile per gli sviluppatori, a meno che non abbiano scritto i propri plug-in che hanno reagito a cacheWillMatch.
  • La sintassi per specificare i plug-in durante la configurazione di una strategia è cambiata. Ogni plug-in deve essere esplicitamente elencato nella proprietà plugins della configurazione della strategia.

Il seguente codice nella v2:

const workboxSW = new self.WorkboxSW();

const networkFirstStrategy = workboxSW.strategies.networkFirst({
  cacheName: 'my-cache',
  networkTimeoutSeconds: 5,
  cacheExpiration: {
    maxEntries: 50,
  },
  cacheableResponse: {
    statuses: [0, 200],
  },
});

ha un equivalente v3 di:

const networkFirstStrategy = workbox.strategies.networkFirst({
  cacheName: 'my-cache',
  networkTimeoutSeconds: 5,
  plugins: [
    new workbox.expiration.Plugin({maxEntries: 50}),
    new workbox.cacheableResponse.Plugin({statuses: [0, 200]}),
  ],
});

Per ulteriori informazioni, consulta la guida "Utilizzo dei plug-in".

workbox-sw

  • Intrinsecamente, workbox-sw è stato riscritto in modo da essere un'interfaccia "loader" leggera, che richiede una configurazione di base ed è responsabile del pull degli altri moduli necessari in fase di runtime. Anziché creare una nuova istanza della classe WorkboxSW, gli sviluppatori interagiranno con un'istanza esistente che viene esposta automaticamente nello spazio dei nomi globale.

In precedenza nella versione 2:

importScripts('<path to workbox-sw>/importScripts/workbox-sw.prod.v2.1.3.js');

const workbox = new WorkboxSW({
  skipWaiting: true,
  clientsClaim: true,
  // etc.
});

workbox.router.registerRoute(...);

Nella versione 3 è sufficiente importare lo script workbox-sw.js e un'istanza pronta all'uso sarà automaticamente disponibile nello spazio dei nomi globale come workbox:

importScripts('<path to workbox-sw>/3.0.0/workbox-sw.js');

// workbox is implicitly created and ready for use.
workbox.routing.registerRoute(...);
  • skipWaiting e clientsClaim non sono più opzioni passate al costruttore WorkboxSW. Sono stati invece modificati i metodi workbox.clientsClaim() e workbox.skipWaiting().
  • L'opzione handleFetch, che in precedenza era supportata nel costruttore v2, non è più supportata nella versione 3. Gli sviluppatori che hanno bisogno di una funzionalità simile per testare il service worker senza dover richiamare alcun gestore di recupero possono utilizzare l'opzione"Escludi per la rete" disponibile negli Strumenti per sviluppatori di Chrome.
L&#39;opzione Bypassa per la rete in Chrome DevTools.

plug-in-webpack-workbox

Il plug-in è stato sostanzialmente riscritto e, in molti casi, può essere utilizzato in modalità di "configurazione zero". Consulta la documentazione per la piattaforma API aggiornata.

  • L'API ora espone due classi, GenerateSW e InjectManifest. In questo modo, è esplicito il passaggio da una modalità all'altra rispetto al comportamento della v2, in cui il comportamento è cambiato in base alla presenza di swSrc.
  • Per impostazione predefinita, gli asset nella pipeline di compilazione Webpack verranno pre-memorizzati nella cache e non è più necessario configurare globPatterns. L'unico motivo per continuare a utilizzare globPatterns è se devi pre-memorizzare nella cache gli asset che non sono inclusi nella build del tuo pacchetto web. In generale, quando esegui la migrazione al plug-in v3, devi innanzitutto rimuovere tutta la configurazione precedente basata su glob e aggiungerla di nuovo solo se ti occorre in modo specifico.

Richiesta di aiuto

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