Migreer van Workbox v4 naar v5

Deze handleiding is gericht op het doorbreken van de wijzigingen die in Workbox v5 zijn geïntroduceerd, met voorbeelden van de wijzigingen die u moet aanbrengen bij het upgraden van Workbox v4.

Veranderingen doorbreken

Plug-inklassen hernoemd

Een aantal Workbox v4-pakketten bevatten klassen met de naam Plugin . In v5 zijn deze klassen hernoemd om de patroonpakket-ID + Plugin in te volgen:

  • BackgroundSyncPlugin
  • BroadcastUpdatePlugin
  • CacheableResponsePlugin
  • ExpirationPlugin
  • RangeRequestsPlugin

Deze hernoeming is van toepassing, ongeacht of u de klassen gebruikt via module-import of via de workbox.* naamruimten.

Standaard Precache Manifest Vervangingspunt

Als u eerder een van de buildtools in de modus 'inject manifest' gebruikte, werd uw werkbestand van de bronservice gecontroleerd op de aanwezigheid van precacheAndRoute([]) , waarbij die lege array [] werd gebruikt als tijdelijke aanduiding voor het punt waarop de precache manifest werd geïnjecteerd.

In Workbox v5 is de vervangingslogica gewijzigd en wordt nu self.__WB_MANIFEST standaard als injectiepunt gebruikt.

// v4:
precacheAndRoute([]);

// v5:
precacheAndRoute(self.__WB_MANIFEST);

Zoals uiteengezet in deze discussie , zijn we van mening dat deze wijziging een eenvoudigere ervaring biedt, terwijl ontwikkelaars tegelijkertijd meer controle krijgen over de manier waarop het geïnjecteerde manifest wordt gebruikt in aangepaste servicewerknemerscode. Indien nodig kunt u deze vervangende string wijzigen via de injectionPoint configuratieoptie.

Twee opties die voorheen werden ondersteund voor navigatieroutes, blacklist en whitelist zijn hernoemd naar denylist en allowlist .

workbox-routing ondersteunde eerder een methode, registerNavigationRoute() , die onder de motorkap twee dingen deed:

  1. Gedetecteerd of een bepaalde fetch al dan niet de mode 'navigate' had.
  2. Als dat het geval is, beantwoordt u dat verzoek met behulp van de inhoud van een eerder in de cache opgeslagen, hardgecodeerde URL, ongeacht de URL waarnaar wordt genavigeerd.

Dit is een veelgebruikt patroon bij het implementeren van de App Shell-architectuur .

De tweede stap, het genereren van een antwoord door uit de cache te lezen, valt buiten wat wij zien als de verantwoordelijkheden van workbox-routing . In plaats daarvan zien we het als functionaliteit die deel zou moeten uitmaken van workbox-precaching , via een nieuwe methode, createHandlerBoundToURL() . Deze nieuwe methode kan hand in hand werken met de bestaande klasse NavigationRoute in workbox-routing om dezelfde logica te bereiken.

Als u de optie navigateFallback gebruikt in een van de 'SW genereren'-modi van de bouwtool, zal de omschakeling automatisch plaatsvinden. Als u eerder de opties navigateFallbackBlacklist of navigateFallbackWhitelist hebt geconfigureerd, wijzigt u deze in respectievelijk navigateFallbackDenylist of navigateFallbackAllowlist .

Als u de modus "inject manifest" gebruikt of de servicemedewerker zelf schrijft, en uw Workbox v4-servicemedewerker roept registerNavigationRoute() rechtstreeks aan, dan moet u een wijziging in uw code aanbrengen om hetzelfde gedrag te krijgen.

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

U hoeft getCacheKeyForURL() niet langer aan te roepen, omdat createHandlerBoundToURL() dat voor u regelt.

Verwijdering van makeRequest() uit workbox-strategieën

Het aanroepen van makeRequest() is grotendeels gelijk aan het aanroepen van handle() in een van de workbox-strategy . De verschillen tussen de twee methoden waren zo klein dat het geen zin had om ze allebei te behouden. Ontwikkelaars die makeRequest() hebben aangeroepen, zouden zonder verdere wijzigingen moeten kunnen overschakelen naar het gebruik handle() :

// v4:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.makeRequest({event, request});

// v5:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.handle({event, request});

In v5 behandelt handle() request als een vereiste parameter en zal niet terugvallen op het gebruik event.request . Zorg ervoor dat u een geldig verzoek doorgeeft wanneer u handle() aanroept.

workbox-broadcast-update Gebruikt altijd postMessage()

In v4 zou de workbox-broadcast-update bibliotheek standaard de Broadcast Channel API gebruiken voor het verzenden van berichten wanneer deze werd ondersteund, en alleen terugvallen op het gebruik van postMessage() wanneer Broadcast Channel niet werd ondersteund.

We realiseerden ons dat het moeten luisteren naar twee potentiële bronnen van inkomende berichten het schrijven van code aan de clientzijde te ingewikkeld maakte. Bovendien worden in sommige browsers postMessage() aanroepen van de servicemedewerker die naar clientpagina's worden verzonden, automatisch gebufferd totdat er een message is ingesteld. Er is geen buffering met de Broadcast Channel API, en uitgezonden berichten worden gewoon verwijderd als ze worden verzonden voordat een clientpagina klaar is om ze te ontvangen.

Om deze redenen hebben we workbox-broadcast-update gewijzigd om altijd postMessage() te gebruiken in v5. Berichten worden één voor één verzonden naar alle klantpagina's binnen het bereik van de huidige servicemedewerker.

Om aan dit nieuwe gedrag tegemoet te komen, kunt u alle code verwijderen die u had op clientpagina's die BroadcastChannel instanties hebben gemaakt, en in plaats daarvan een message instellen op 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 ...
  }
});

gebruikers workbox-window hoeven geen wijzigingen aan te brengen, omdat de interne logica ervan is bijgewerkt om te luisteren naar postMessage() aanroepen.

Build Tools Vereist Node.js v8 of hoger

Node.js-versies vóór v8 worden niet langer ondersteund voor workbox-webpack-plugin , workbox-build workbox-cli . Als u een Node.js-versie ouder dan 8 gebruikt, update dan uw runtime naar een ondersteunde versie .

workbox-webpack-plugin Vereist webpack v4 of hoger

Als u workbox-webpack-plugin gebruikt, update dan uw webpack-instellingen zodat u ten minste webpack v4 gebruikt.

Revisie van buildtooloptie

Een aantal configuratieparameters workbox-build , workbox-cli en workbox-webpack-plugin worden niet langer ondersteund. generateSW zal bijvoorbeeld altijd een lokale Workbox-runtimebundel voor u maken, dus de importWorkboxFrom optie heeft niet langer zin.

Raadpleeg de documentatie van het betreffende hulpmiddel voor de lijsten met ondersteunde opties.

Verwijdering van genererenSWString uit workbox-build

De generateSWString -modus is verwijderd uit workbox-build . We verwachten dat de impact hiervan minimaal zal zijn, aangezien het voornamelijk intern werd gebruikt door workbox-webpack-plugin .

Optionele wijzigingen

Module-import gebruiken

Hoewel deze verandering a) optioneel is en b) technisch mogelijk was bij het gebruik van Workbox v4, is de grootste verandering die we verwachten bij de overstap naar v5 een model waarin u uw eigen gebundelde servicemedewerker creëert door de modules van Workbox te importeren. Deze aanpak is een alternatief voor het aanroepen van importScripts('/path/to/workbox-sw.js') bovenaan uw service worker, en het gebruik van Workbox via de workbox.* naamruimte.

Als u een van de bouwtools gebruikt ( workbox-webpack-plugin , workbox-build , workbox-cli ) in de modus "SW genereren", dan zal deze wijziging automatisch voor u plaatsvinden. Al deze tools zullen een lokale, aangepaste bundel van de Workbox-runtime uitvoeren, naast de daadwerkelijke code die nodig is om de logica van uw servicemedewerkers te implementeren. In dit scenario is er niet langer enige afhankelijkheid van workbox-sw of de CDN-kopie van Workbox. Afhankelijk van de waarde van uw inlineWorkboxRuntime configuratie, wordt de Workbox-runtime opgesplitst in een afzonderlijk bestand dat naast uw service worker moet worden geïmplementeerd (indien ingesteld op false , wat de standaard is), of inline opgenomen samen met de service worker-logica ( wanneer ingesteld op true ).

Als u de build-tools in de "inject manifest"-modus gebruikt, of als u de build-tools van Workbox helemaal niet gebruikt, kunt u meer leren over het maken van uw eigen Workbox-runtimebundel in de bestaande Bundlers gebruiken (webpack/Rollup) met Gids voor werkdozen .

De documentatie en voorbeelden voor v5 zijn geschreven in de veronderstelling dat de module importeert, hoewel de naamruimte workbox.* ondersteund blijft in Workbox v5.

Vooraf in de cache opgeslagen antwoorden lezen

Sommige ontwikkelaars moeten vooraf in de cache opgeslagen antwoorden rechtstreeks uit de cache lezen, in plaats van ze impliciet te gebruiken via de precacheAndRoute() -methode. Een gebruikelijk patroon in v4 zou zijn om eerst de cachesleutel op te halen die specifiek is voor de huidige versie van een vooraf in de cache opgeslagen bron, en vervolgens die sleutel samen met de cachenaam van de precache door te geven aan caches.match() om de Response te krijgen.

Om dit proces te vereenvoudigen ondersteunt workbox-precaching in v5 een nieuwe, gelijkwaardige methode, 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`);

TypeScript-adoptie

In v5 zijn de Workbox-runtimebibliotheken geschreven in TypeScript . Hoewel we getranspileerde JavaScript-modules en -bundels zullen blijven publiceren voor ontwikkelaars die TypeScript niet hebben geadopteerd, zou u, als u TypeScript gebruikt, kunnen profiteren van nauwkeurige, altijd actuele type-informatie rechtstreeks uit het Workbox-project.

Voorbeeld migratie

Deze commit illustreert dat het een tamelijk ingewikkelde migratie is, met inline commentaar. Er wordt gebruik gemaakt van Rollup om een ​​aangepaste Workbox-runtime op te nemen in de uiteindelijke servicemedewerker in plaats van de runtime vanuit het CDN te laden.

Hoewel niet alle belangrijke wijzigingen worden behandeld, vindt u hier het voor en na het upgraden van een servicemedewerkerbestand van v4 naar v5, inclusief een overstap naar TypeScript.

Hulp krijgen

We verwachten dat de meeste migraties eenvoudig zullen zijn. Als u problemen tegenkomt die niet in deze handleiding worden behandeld, kunt u ons dit laten weten door een probleem op GitHub te openen .