Migracja z Workbox 4 do 5

Ten przewodnik skupia się na zmianach powodujących niezgodność wprowadzonych w Workbox v5. Zawiera też przykłady zmian, które należy wprowadzić przy przejściu z Workbox v4.

Zmiany powodujące niezgodność

Zmieniono nazwy zajęć wtyczek

Niektóre pakiety Workbox w wersji 4 zawierały klasy o nazwie Plugin. W wersji 5 nazwy tych klas zostały zmienione, tak aby były zgodne z identyfikatorem pakietu wzorca + Plugin:

  • BackgroundSyncPlugin
  • BroadcastUpdatePlugin
  • CacheableResponsePlugin
  • ExpirationPlugin
  • RangeRequestsPlugin

Ta zmiana nazwy dotyczy klas używanych w ramach importowania modułów lub w ramach przestrzeni nazw workbox.*.

Domyślny punkt zastępowania pliku manifestu wstępnego buforowania

Wcześniej, gdy używano jednego z narzędzi kompilacji w trybie „wstrzyknięcia pliku manifestu”, sprawdzano, czy plik źródłowy usługi roboczej zawiera precacheAndRoute([]). Pusty tablica [] była używana jako miejsce docelowe wstrzyknięcia pliku manifestu domyślnego.

W Workbox w wersji 5 zmieniła się logika zastępowania i teraz domyślnym punktem wstrzykiwania jest self.__WB_MANIFEST.

// v4:
precacheAndRoute([]);

// v5:
precacheAndRoute(self.__WB_MANIFEST);

Jak opisano w tej dyskusji, ta zmiana upraszcza obsługę, a jednocześnie daje deweloperom większą kontrolę nad sposobem używania wstrzykniętego pliku manifestu w ramach niestandardowego kodu usługi. W razie potrzeby możesz zmienić ten ciąg zastępczy za pomocą opcji konfiguracji injectionPoint.

2 opcje, które były wcześniej obsługiwane w przypadku tras nawigacji, blacklistwhitelist, zostały przemianowane na denylistallowlist.

Interfejs workbox-routing obsługiwał wcześniej metodę registerNavigationRoute(), która pod maską robiła 2 rzeczy:

  1. Wykryto, czy dane zdarzenie fetch miało mode o wartości 'navigate'.
  2. Jeśli tak, odpowiedź na żądanie skorzystała z zakodowanego na stałe adresu URL zapisanego na stałe w pamięci podręcznej, niezależnie od tego, do którego adresu URL przechodzi użytkownik.

To typowy wzorzec używany przy wdrażaniu architektury App Shell.

Drugi etap, generowanie odpowiedzi przez odczyt z pamięci podręcznej, wykracza poza zakres odpowiedzialności usługi workbox-routing. Uważamy ją za funkcję, która powinna być częścią workbox-precaching w ramach nowej metody – createHandlerBoundToURL(). Ta nowa metoda może działać równolegle z dotychczasową klasą NavigationRoute w narzędziu workbox-routing, aby osiągnąć to samo.

Jeśli używasz opcji navigateFallback w jednym z trybów „generuj SW” narzędzia do kompilacji, przełączenie nastąpi automatycznie. Jeśli masz już skonfigurowane opcje navigateFallbackBlacklist lub navigateFallbackWhitelist, zmień je na odpowiednio navigateFallbackDenylist lub navigateFallbackAllowlist.

Jeśli używasz opcji „wstrzyknij plik manifestu” lub po prostu napisać skrypt service worker własnoręcznie, a skrypt service workbox v4 wywoła bezpośrednio registerNavigationRoute(), musisz wprowadzić zmianę w kodzie, aby uzyskać jego odpowiednik.

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

Nie musisz już dzwonić do getCacheKeyForURL(), ponieważ createHandlerBoundToURL() załatwi to za Ciebie.

Usunięcie metody MakeRequest() ze strategii Workbox

Wywołanie makeRequest() jest w większości przypadków równoważne wywołaniu handle() w jednym z obiektów klasy workbox-strategy. Różnice między obiema metodami były na tyle niewielkie, że respektowanie obu nie miało sensu. Deweloperzy, którzy wywoływali funkcję makeRequest(), powinni móc przejść na korzystanie z funkcji handle() bez wprowadzania dalszych zmian:

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

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

W wersji 5 funkcja handle() traktuje parametr request jako wymagany parametr i nie przełącza się na użycie event.request. Podczas wywoływania funkcji handle() podaj prawidłową prośbę.

workbox-broadcast-update Always Uses postMessage()

W wersji 4 biblioteka workbox-broadcast-update domyślnie używała interfejsu Broadcast Channel API do wysyłania wiadomości, jeśli był on obsługiwany, i wracał do używania postMessage() tylko wtedy, gdy kanał transmisji nie był obsługiwany.

Zauważyliśmy, że pisanie kodu po stronie klienta jest niezwykle skomplikowane. Dodatkowo w niektórych przeglądarkach wywołania postMessage() z skryptu service worker wysyłane na strony klienta są automatycznie buforowane do momentu skonfigurowania detektora zdarzeń message. Interfejs Broadcast Channel API nie umożliwia buforowania, a wysyłane wiadomości są po prostu pomijane, jeśli zostaną wysłane, zanim strona klienta będzie gotowa do ich odebrania.

Dlatego zmieniliśmy workbox-broadcast-update, by zawsze używał postMessage() w wersji 5. Wiadomości są wysyłane pojedynczo do wszystkich stron klienta w zakresie bieżącego pracownika serwisu.

Aby dostosować się do tego nowego zachowania, możesz usunąć cały kod ze stron klienta, na których utworzono instancje BroadcastChannel, a potem skonfigurować detektor zdarzeń message w systemie 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 ...
  }
});

Użytkownicy workbox-window nie powinni wprowadzać żadnych zmian, ponieważ jej wewnętrzna logika jest teraz odbierana przez wywołania postMessage().

Narzędzia do kompilacji wymagają środowiska Node.js w wersji 8 lub nowszej

Wersje Node.js starsze niż 8 nie są już obsługiwane w workbox-webpack-plugin, workbox-build ani workbox-cli. Jeśli używasz środowiska Node.js w wersji wcześniejszej niż 8, zaktualizuj środowisko wykonawcze do obsługiwanej wersji.

Workbox-webpack-plugin Wymaga pakietu webpack w wersji 4 lub nowszej

Jeśli używasz workbox-webpack-plugin, zaktualizuj konfigurację webpacka, aby używać co najmniej webpacka w wersji 4.

Ulepszenie opcji narzędzi do kompilacji

Niektóre parametry konfiguracji workbox-build, workbox-cli oraz workbox-webpack-plugin nie są już obsługiwane. Na przykład generateSW zawsze utworzy dla Ciebie lokalny pakiet środowiska wykonawczego Workbox, więc opcja importWorkboxFrom nie ma już sensu.

Listę obsługiwanych opcji znajdziesz w dokumentacji danego narzędzia.

Usunięcie funkcji generateSWString z workbox-build

Tryb generateSWString został usunięty z funkcji workbox-build. Spodziewamy się, że wpływ tej zmiany będzie minimalny, ponieważ usługa ta była używana głównie wewnętrznie przez workbox-webpack-plugin.

Zmiany opcjonalne

Korzystanie z importów modułów

Choć ta zmiana jest a) opcjonalna i b) technicznie była możliwa w przypadku korzystania z Workbox v4, największą zmianą, której oczekujemy po przejściu na wersję 5, będzie model, w którym utworzysz własny pakiet instancji roboczych przez zaimportowanie modułów Workbox. To podejście jest alternatywą dla wywołania importScripts('/path/to/workbox-sw.js') na początku usługi roboczej i używania Workboxa za pomocą przestrzeni nazw workbox.*.

Jeśli używasz jednego z narzędzi do kompilacji (workbox-webpack-plugin, workbox-build, workbox-cli) w trybie „generuj SW”, ta zmiana zostanie wprowadzona automatycznie. Wszystkie te narzędzia generują lokalny, niestandardowy pakiet środowiska wykonawczego Workbox wraz z rzeczywistym kodem niezbędnym do implementacji logiki skryptu service worker. W tym scenariuszu nie jest już uzależnione od workbox-sw ani kopii Workbox w CDN. W zależności od wartości konfiguracji inlineWorkboxRuntime środowisko uruchomieniowe Workbox zostanie podzielone na osobny plik, który należy wdrożyć razem z usługą instancją roboczą (jeśli wartość to false, co jest domyślną opcją) lub zostanie dołączony w ramach logiki usługi instancji roboczej (jeśli wartość to true).

Jeśli używasz narzędzi do kompilacji w trybie „wstrzyknięcia manifestu” lub w ogóle nie używasz narzędzi do kompilacji Workbox, więcej informacji o tworzeniu własnego pakietu Workbox na czas wykonywania znajdziesz w dostępnym już przewodniku Korzystanie z pakietu (webpack/Rollup) w Workbox.

Dokumentacja i przykłady dotyczące wersji 5 zostały napisane z założeniem, że użyto składni importowania modułów, ale przestrzeń nazw workbox.* będzie nadal obsługiwana w Workbox w wersji 5.

Czytanie odpowiedzi z poziomu pamięci podręcznej

Niektórzy deweloperzy muszą odczytywać odpowiedzi z pamięci podręcznej bezpośrednio z pamięci podręcznej zamiast używać ich domyślnie za pomocą metody precacheAndRoute(). Typowym wzorcem w wersji 4 jest uzyskanie najpierw klucza pamięci podręcznej specyficznego dla bieżącej wersji zasobu w pamięci podręcznej, a następnie przekazanie tego klucza wraz z nazwą tej pamięci podręcznej do caches.match() w celu uzyskania Response.

Aby uprościć ten proces, workbox-precaching w wersji 5 obsługuje nową, równoważną metodę 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`);

Przyjęcie TypeScript

W wersji 5 biblioteki środowiska wykonawczego Workbox są napisane w języku TypeScript. Chociaż nadal będziemy publikować transpilowane moduły i pakiety JavaScriptu, aby ułatwić życie deweloperom, którzy nie korzystają z TypeScript, jeśli używasz TypeScriptu, możesz korzystać z dokładnych i zawsze aktualnych informacji o typach bezpośrednio z projektu Workbox.

Przykładowa migracja

To zatwierdzenie ilustruje dość skomplikowaną migrację z komentarzem. Wykorzystuje ono funkcję o pełnym zakresie, niestandardowe środowisko wykonawcze Workbox w ostatecznym elemencie service worker zamiast wczytywania środowiska wykonawczego z sieci CDN.

Nie obejmuje ona wszystkich zmian, ale poniżej znajdziesz stan przedpo uaktualnieniu pliku usługi z wersji 4 na 5, w tym przejście na TypeScript.

Uzyskiwanie pomocy

Przewidujemy, że migracja w większości przypadków będzie prosta. Jeśli napotkasz problemy, których nie omówiliśmy w tym przewodniku, daj nam znać, otwierając zgłoszenie na GitHubie.