Eseguire la migrazione da Workbox v2 a v3

Questa guida è incentrata sull'interruzione delle modifiche introdotte in Workbox v3, con esempi di quali modifiche dovresti apportare quando esegui l'upgrade da una configurazione di Workbox v2.

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

Sfondo v3

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

  • Riduci al minimo le dimensioni della Workbox. La quantità di codice di runtime del service worker che è stata scaricata ed eseguita è stata ridotta. Anziché scegliere per tutti un bundle monolitico, durante il runtime verrà importato solo il codice per le funzionalità specifiche in uso.
  • Workbox ha una rete CDN. Forniamo un hosting CDN basato su Google Cloud Storage completamente supportato come opzione canonica per accedere alle librerie di runtime di Workbox, semplificando l'utilizzo di 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. Un esempio del logging di debug offerto da Workbox v3.
  • Plug-in Webpack migliorato. workbox-webpack-plugin si integra meglio con il processo di compilazione webpack, consentendo un caso d'uso zero-config in cui vuoi pre-memorizzare nella cache tutti gli asset nella pipeline di build.

Per raggiungere questi obiettivi e ripulire alcuni aspetti dell'interfaccia precedente che sembravano imbarazzanti o portavano a anti-pattern, era necessario introdurre una serie di modifiche che provocano l'interruzione nella release v3.

Modifiche che provocano un errore

Configurazione build

Le seguenti modifiche 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 valido in precedenza e trattato come un alias per 'staleWhileRevalidate', durante la configurazione di runtimeCaching. Non è più valido e gli sviluppatori dovrebbero passare all'utilizzo diretto di 'staleWhileRevalidate'.
  • Diversi nomi delle proprietà runtimeCaching.options sono stati aggiornati ed è in corso un'ulteriore convalida dei parametri che comporterà l'esito negativo di una build se viene utilizzata una configurazione non valida. Consulta la documentazione relativa a runtimeCaching per un elenco delle opzioni attualmente supportate.

workbox-background-sync

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

workbox-broadcast-cache-update

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

Ad esempio, nella v2 dovresti 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.

workbox-build

  • Per impostazione predefinita, la corrispondenza dei pattern glob verrà ora eseguita con le opzioni follow: true (che seguiranno i link simbolici) e strict: true (che è meno tollerante agli errori "strani"). Puoi disabilitare una delle due opzioni e tornare al comportamento precedente impostando globFollow: false e/o globStrict: false nella configurazione della build.
  • Le funzioni in workbox-build restituiscono tutte una proprietà aggiuntiva, warnings, nelle risposte che restituiscono. Alcuni scenari, trattati come errori irreversibili nella versione 2 sono ora consentiti, ma segnalati tramite warnings, che è un array di stringhe.

Nella versione 2, potresti chiamare generateSW in questo 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, è buona norma verificare gli 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 2 devono restituire l'array manifest in un oggetto (ad esempio, invece di return manifestArray;, è consigliabile utilizzare return {manifest: manifestArray};). In 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 un'istruzione ManifestTransform personalizzata nella versione 2, utilizza questo codice:

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 getManifest() e la promessa restituita ora include informazioni aggiuntive sugli URL che sono stati prememorizzati nella cache.

Codice simile al seguente nella versione 2:

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

può essere riscritto nella versione 3 come:

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 invece getManifest() e di utilizzare la sua risposta per scrivere dati su disco nel formato appropriato.

workbox-cache-expiration

  • L'API plugin è rimasta invariata, che è la modalità che verrà utilizzata dalla maggior parte degli sviluppatori. Tuttavia, ci sono modifiche significative all'API che interessano gli sviluppatori che la utilizzano come corso a sé stante. 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 per l'alias workbox-cli per lo script binario è stato rimosso. Ora è possibile accedere al programma binario solo come workbox.
  • I comandi v2 generate:sw e inject:manifest sono stati rinominati in generateSW e injectManifest nella v3.
  • Nella versione v2, si presuppone che il file di configurazione predefinito (utilizzato quando non ne è stato fornito uno in modo esplicito) nella directory corrente fosse workbox-cli-config.js. Nella versione 3, è workbox-config.js.

Complessivamente, ciò significa che nella versione 2:

$ workbox inject:manifest

eseguirebbe il "file manifest inject" utilizzando una configurazione letta da workbox-cli-config.js e nella versione 3:

$ workbox injectManifest

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

pre-memorizzazione nella cache della casella di lavoro

  • In precedenza, il metodo precache() ha eseguito sia le modifiche della cache sia configurato il routing per pubblicare le voci memorizzate nella cache. Ora precache() modifica solo le voci della cache ed è stato esposto un nuovo metodo, addRoute(), per registrare una route per pubblicare le risposte memorizzate nella cache. Gli sviluppatori che vogliono la funzionalità due in uno precedente possono passare alla chiamata di precacheAndRoute().
  • Diverse opzioni che erano configurate tramite il costruttore WorkboxSW ora vengono passate come parametro options in workbox.precaching.precacheAndRoute([...], options). I valori predefiniti per queste opzioni, se non configurate, sono elencati nella documentazione di riferimento.
  • Per impostazione predefinita, gli URL privi di estensione di file verranno controllati automaticamente per verificare la presenza di una corrispondenza con una voce della cache contenente un'estensione .html. Ad esempio, se viene effettuata una richiesta per /path/to/index (che non è prememorizzata nella cache) ed è presente una voce pre-memorizzata nella cache per /path/to/index.html, verrà utilizzata quella voce pre-memorizzata nella cache. Gli sviluppatori possono disattivare questo nuovo comportamento impostando {cleanUrls: false} al momento di trasferire le opzioni in workbox.precaching.precacheAndRoute().
  • workbox-broadcast-update non sarà più configurato automaticamente per annunciare aggiornamenti della cache per gli asset prememorizzati nella cache.

Il seguente codice nella versione 2:

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-box

  • 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.*.
  • Le route ora vengono valutate in un primo ordine di vittorie registrate. Questo è l'ordine opposto di Route di valutazione usato nella versione 2, in cui l'ultimo Route registrato avrà la precedenza.
  • La classe ExpressRoute e il supporto per "Express-style" i caratteri jolly sono stati rimossi. Ciò riduce notevolmente le dimensioni di workbox-routing. Le stringhe utilizzate come primo parametro per 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 corrispondente a parte o all'intero URL della richiesta può attivare una route.
  • Il metodo helper addFetchListener() della classe Router è stato rimosso. Gli sviluppatori possono aggiungere il proprio gestore fetch in modo esplicito oppure utilizzare l'interfaccia fornita da workbox.routing, che creerà implicitamente per loro un gestore fetch.
  • 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ù route contemporaneamente devono effettuare invece una serie di chiamate a registerRoute() o unregisterRoute().

Il seguente codice nella versione 2:

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()
);

workbox-strategie (precedentemente note come workbox-runtime-caching)

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

Ciò porterebbe a voci in scadenza nella cache predefinita, il che è inaspettato. Nella v3, un nome cache è obbligatorio:

workboxSW.strategies.staleWhileRevalidate({
  cacheName: 'my-cache',
  plugins: [new workbox.expiration.Plugin({maxEntries: 50})],
});
  • Il metodo del ciclo di vita cacheWillMatch è stato rinominato in cachedResponseWillBeUsed. Questo non dovrebbe essere un cambiamento visibile per gli sviluppatori, a meno che non abbiano scritto 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 elencato esplicitamente nella proprietà plugins della configurazione della strategia.

Il seguente codice nella versione 2:

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]}),
  ],
});

Puoi trovare ulteriori informazioni nella pagina "Utilizzo dei plug-in" guida.

workbox-sw

  • dietro le quinte, workbox-sw è stato riscritto per essere un "loader" leggero 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 è 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 v3, è 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. Al loro posto, sono stati applicati i metodi workbox.clientsClaim() e workbox.skipWaiting().
  • L'opzione handleFetch precedentemente supportata nel costruttore v2 non è più supportata nella versione 3. Gli sviluppatori che hanno bisogno di una funzionalità simile per testare il proprio service worker senza che vengano richiamati gestori di recupero possono usare l'opzione "Bypass for network" (Ignora per la rete). disponibile negli Strumenti per sviluppatori di Chrome.
L&#39;opzione Bypassa la rete in Chrome DevTools.

workbox-webpack-plugin

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

  • L'API ora espone due classi, GenerateSW e InjectManifest. Ciò rende esplicita l'attivazione/disattivazione da una modalità all'altra rispetto a quella della versione 2, in cui il comportamento cambia in base alla presenza di swSrc.
  • Per impostazione predefinita, gli asset nella pipeline di compilazione webpack verranno prememorizzati nella cache e la configurazione di globPatterns non sarà più necessario. L'unico motivo per continuare a utilizzare globPatterns è se devi prememorizzare nella cache gli asset che non sono inclusi nella build del webpack. In generale, durante la migrazione al plug-in v3, dovresti iniziare rimuovendo tutta la configurazione precedente basata su glob e riaggiungila solo se ti serve specificamente.

Richiesta di aiuto

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