Migracja z Workbox 4 do 5

Ten przewodnik koncentruje się na istotnych zmianach wprowadzonych w Workbox v5 i pokazuje przykłady zmian, które trzeba wprowadzić podczas uaktualniania z Workbox v4.

Niezbędne zmiany

Zmieniono nazwy klas wtyczek

Niektóre pakiety Workbox w wersji 4 zawierały klasy o nazwie Plugin. W wersji 5 nazwy tych klas zostały zmienione, aby odpowiadały identyfikatorowi pakietu wzorców + Plugin:

  • BackgroundSyncPlugin
  • BroadcastUpdatePlugin
  • CacheableResponsePlugin
  • ExpirationPlugin
  • RangeRequestsPlugin

Zmiana nazwy ma zastosowanie niezależnie od tego, czy używasz klas za pomocą importowania modułów czy przez przestrzenie nazw workbox.*.

Domyślny punkt zastępowania pliku manifestu Precache

Wcześniej podczas korzystania z jednego z narzędzi kompilacji w trybie „wstrzyknij plik manifestu” źródłowy plik roboczy usługi był sprawdzany pod kątem obecności precacheAndRoute([]), a pusta tablica [] była wykorzystywana jako zmienna oznaczająca moment, w którym wstrzyknięto plik manifestu precache.

W Workbox w wersji 5 logika zastępowania zmieniła się. Teraz punktem wstrzykiwania jest self.__WB_MANIFEST.

// v4:
precacheAndRoute([]);

// v5:
precacheAndRoute(self.__WB_MANIFEST);

Jak zaznaczyliśmy w tym artykule, uważamy, że zmiana ta uprości korzystanie z platformy, a jednocześnie da deweloperom większą kontrolę nad sposobem używania wstrzykiwanego pliku manifestu w kodzie niestandardowego skryptu service worker. W razie potrzeby możesz go zmienić za pomocą opcji konfiguracji injectionPoint.

Dwie opcje, które wcześniej były obsługiwane w przypadku tras nawigacji (blacklist i whitelist), zostały zmienione na denylist i allowlist.

Przeglądarka workbox-routing obsługiwała wcześniej metodę registerNavigationRoute(), która zasadniczo zapewniała 2 rzeczy:

  1. Wykryto, czy dane zdarzenie fetch miało mode o wartości 'navigate'.
  2. Jeśli tak, odpowiedź na to żądanie przy użyciu treści wcześniejszego, zakodowanego na stałe adresu URL w pamięci podręcznej, niezależnie od otwartego adresu URL.

Jest to często używany wzorzec podczas wdrażania architektury App Shell.

Drugi etap, generowanie odpowiedzi przez odczytanie danych z pamięci podręcznej, nie leży w zakresie obowiązków usługi workbox-routing. Uważamy, że jest to funkcja, która powinna być dostępna w workbox-precaching za pomocą nowej metody: createHandlerBoundToURL(). Ta nowa metoda może współpracować z dotychczasową klasą NavigationRoute w usłudze workbox-routing, aby uzyskać tę samą logikę.

Jeśli używasz opcji navigateFallback w trybie „generowania kodu SW” narzędzia do tworzenia, przełączenie nastąpi automatycznie. Jeśli masz skonfigurowane wcześniej opcje navigateFallbackBlacklist lub navigateFallbackWhitelist, zmień je odpowiednio na navigateFallbackDenylist lub navigateFallbackAllowlist.

Jeśli używasz trybu „wstrzyknij plik manifestu” lub po prostu tworzysz skrypt service worker, a skrypt service workbox v4 bezpośrednio wywołuje registerNavigationRoute(), musisz wprowadzić zmianę w kodzie, aby uzyskać analogiczne działanie.

// 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ć pod numer getCacheKeyForURL(), ponieważ createHandlerBoundToURL() zajmie się tym za Ciebie.

Usunięcie funkcji MakeRequest() ze strategii skrzynki roboczej

Wywołanie makeRequest() jest w większości równoważne z wywołaniem metody handle() w jednej z klas workbox-strategy. Różnice między tymi metodami były tak niewielkie, że pozostawienie ich w obu przypadkach nie miało sensu. Deweloperzy, którzy wywołali funkcję makeRequest(), powinni mieć możliwość przejścia na handle() bez żadnych 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 request jako parametr wymagany i nie przełącza się na użycie event.request. Zadbaj o to, by przed wywołaniem handle() przekazać prawidłowe żądanie.

workbox-broadcast-update Zawsze używa postMessage()

W wersji 4 biblioteka workbox-broadcast-update będzie domyślnie używać interfejsu Broadcast Channel API do wysyłania wiadomości, gdy będzie on obsługiwany. Z kolei postMessage() będzie używać tylko wtedy, gdy kanał naziemny nie był obsługiwany.

Zdaliśmy sobie sprawę, że pisanie kodu po stronie klienta staje się zbyt skomplikowane, ponieważ wychwytuje 2 potencjalne źródła wiadomości przychodzących. Dodatkowo w niektórych przeglądarkach wywołania postMessage() z skryptu service worker wysyłane na strony klienta są automatycznie buforowane do czasu skonfigurowania odbiornika zdarzeń message. Interfejs Broadcast Channel API nie umożliwia buforowania. Rozgłaszane wiadomości są po prostu usuwane, jeśli zostały wysłane, zanim strona klienta będzie gotowa do ich odbioru.

Dlatego zmieniliśmy funkcję workbox-broadcast-update, aby w wersji 5 zawsze używała funkcji postMessage(). Wiadomości są wysyłane pojedynczo do wszystkich stron klientów w zakresie bieżącego skryptu service worker.

Aby dostosować się do tego nowego sposobu działania, usuń cały kod ze stron klienta, które utworzyły wystąpienia typu BroadcastChannel. Zamiast tego skonfiguruj odbiornik zdarzeń message na stronie 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ż wewnętrzna logika została zaktualizowana pod kątem nasłuchiwania wywołań 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 przez workbox-webpack-plugin, workbox-build ani workbox-cli. Jeśli używasz środowiska Node.js w wersji starszej niż 8, zaktualizuj środowisko wykonawcze do obsługiwanej wersji.

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

Jeśli korzystasz z workbox-webpack-plugin, zaktualizuj konfigurację pakietu internetowego, aby używać pakietu w wersji co najmniej 4.

Remont opcji narzędzi do kompilacji

Kilka parametrów konfiguracji workbox-build, workbox-cli i workbox-webpack-plugin nie jest już obsługiwane. Na przykład generateSW zawsze tworzy 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 elementu generateSWString z tworzenia skrzynki roboczej

Tryb generateSWString został usunięty z workbox-build. Spodziewamy się, że wpływ będzie to minimalny, ponieważ był używany głównie przez aplikację workbox-webpack-plugin.

Opcjonalne zmiany

Korzystanie z importowania modułów

Chociaż ta zmiana jest a) opcjonalna i b) technicznie możliwa do wprowadzenia w przypadku korzystania z Workbox w wersji 4, największą przewidzianą przez nas zmianą przy przejściu na wersję 5 jest model polegający na tworzeniu własnego pakietu instancji roboczej poprzez importowanie modułów Workbox. Ta metoda jest alternatywą dla wywoływania importScripts('/path/to/workbox-sw.js') u góry skryptu service worker i używania skrzynki roboczej 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 oraz rzeczywisty kod niezbędny do implementacji logiki skryptu service worker. W tym scenariuszu nie jest już zależność od workbox-sw ani kopii CDN listy Workbox. W zależności od wartości konfiguracji inlineWorkboxRuntime środowisko wykonawcze Workbox zostanie podzielone na oddzielny plik, który powinien być wdrożony wraz z skryptem service worker (gdy jest ustawiony na false, co jest domyślną wartością), lub zawarte w tekście wraz z logiką skryptu service worker (gdy jest ustawiona wartość true).

Jeśli używasz narzędzi do kompilacji w trybie „wstrzyknij plik manifestu” lub w ogóle nie używasz narzędzi do kompilacji Workbox, więcej informacji o tworzeniu własnego pakietu środowiska wykonawczego Workbox znajdziesz w przewodniku Korzystanie z pakietów (webpack/Rollup) with Workbox.

Dokumentacja i przykłady dotyczące wersji 5 są opracowane przy założeniu, że moduł importuje składnię, ale przestrzeń nazw workbox.* będzie nadal obsługiwana w Workbox w wersji 5.

Odczytywanie odpowiedzi z 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 metody precacheAndRoute(). Typowym wzorcem w wersji 4 jest pobranie klucza pamięci podręcznej specyficznego dla bieżącej wersji wstępnie zapisanego zasobu, a następnie przekazanie tego klucza wraz z nazwą pamięci podręcznej precache 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`);

Przystosowanie TypeScriptu

W wersji 5 biblioteki środowiska wykonawczego Workbox są zapisywane w języku TypeScript. Nadal będziemy publikować transpilowane moduły i pakiety JavaScript, aby ułatwić pracę deweloperom, którzy nie korzystali z TypeScript. Jeśli jednak korzystasz z TypeScriptu, informacje o typie powinny być zawsze aktualne i dokładne bezpośrednio w projekcie Workbox.

Przykładowa migracja

To zatwierdzenie pokazuje, jak migracja jest w dużej stopniu zaangażowana i zawiera komentarze w tekście. Wykorzystuje ono funkcję o pełnym zakresie, aby zamiast wczytywania środowiska wykonawczego z sieci CDN uwzględnić w końcowym mechanizmie Service Workbox niestandardowe środowisko wykonawcze Workbox.

Chociaż nie obejmuje on wszystkich zmian powodujących niezgodność, tutaj znajdziesz informacje o zmianach w postaci zmian powodujących niezgodność, ale o uaktualnieniu jednego pliku mechanizmów Service Worker z wersji 4 do 5 (w tym o przejście na TypeScript) znajdziesz przed i po jego uaktualnieniu.

Jak uzyskać pomoc

Przewidujemy, że większość migracji będzie prosta. Jeśli napotkasz problemy, które nie zostały opisane w tym przewodniku, daj nam znać, otwierając je na GitHubie.