Migracja z Workbox 5 do 6

Ten przewodnik koncentruje się na zmianach powodujących niezgodność wprowadzonych w Workbox v6 i zawiera przykłady zmian, które trzeba wprowadzić podczas uaktualniania z Workbox v5.

Zmiany powodujące niezgodność

workbox-core

Metoda skipWaiting() w workbox-core nie będzie już dodawać modułu obsługi install i będzie równoważna wywołaniu self.skipWaiting().

Od teraz używaj self.skipWaiting(), ponieważ skipWaiting() prawdopodobnie zostanie usunięty w Workbox v7.

workbox-precaching

  • Dokumenty HTML z różnych źródeł w przypadku adresów URL, które odpowiadają przekierowaniu HTTP, nie mogą już być używane do obsługi żądania nawigacji za pomocą workbox-precaching. Taka sytuacja zdarza się rzadko.
  • Parametr zapytania URL fbclid jest teraz ignorowany przez workbox-precaching podczas wyszukiwania wstępnie zapisanej odpowiedzi na dane żądanie.
  • Konstruktor PrecacheController przyjmuje teraz jako parametr obiekt z określonymi właściwościami, a nie ciąg znaków. Ten obiekt obsługuje te właściwości: cacheName (służy do tego samego celu co ciąg znaków przekazany do konstruktora w wersji 5), plugins (zastępuje metodę addPlugins() z wersji 5) i fallbackToNetwork (zastępuje podobną opcję przekazaną do createHandler() i `createHandlerBoundToURL() w wersji 5).
  • Metody install() i activate() klasy PrecacheController przyjmują teraz dokładnie 1 parametr, który powinien być ustawiony odpowiednio na InstallEvent lub ActivateEvent.
  • Metoda addRoute() została usunięta z PrecacheController. Zamiast tego możesz użyć nowej klasy PrecacheRoute, aby utworzyć trasę, którą następnie możesz zarejestrować.
  • Metoda precacheAndRoute() została usunięta z PrecacheController. (Nadal istnieje jako statyczna metoda pomocnicza eksportowana przez moduł workbox-precaching). Została usunięta, ponieważ zamiast niej można używać zasady PrecacheRoute.
  • Metoda createMatchCalback() została usunięta z PrecacheController. Zamiast tego możesz użyć nowego elementu PrecacheRoute.
  • Metoda createHandler() została usunięta z PrecacheController. Zamiast tego do obsługi żądań można użyć właściwości strategy obiektu PrecacheController.
  • Eksport statyczny createHandler() został już usunięty z modułu workbox-precaching. Zamiast tego deweloperzy powinni utworzyć instancję PrecacheController i użyć jej właściwości strategy.
  • Trasa zarejestrowana w precacheAndRoute() jest teraz „prawdziwą” trasą, która wykorzystuje klasę Router workbox-routing. Może to spowodować inną kolejność oceny tras, jeśli przeplatasz wywołania registerRoute() i precacheAndRoute().

workbox-routing

Metoda setDefaultHandler() przyjmuje teraz opcjonalny drugi parametr odpowiadający metodzie HTTP, do której się odnosi. Domyślnie jest to 'GET'.

  • Jeśli używasz setDefaultHandler() i wszystkie Twoje żądania są GET, nie musisz wprowadzać żadnych zmian.
  • Jeśli masz jakieś prośby, które nie są GET (POST, PUT itp.), setDefaultHandler() nie będzie już powodować dopasowania tych żądań.

Konfiguracja kompilacji

Opcja mode dla trybów getManifest i injectManifest w workbox-build i workbox-cli nie miała być obsługiwana i została usunięta. Nie dotyczy to workbox-webpack-plugin, który obsługuje mode we wtyczce InjectManifest.

Narzędzia do kompilacji wymagają Node.js w wersji 10 lub nowszej

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

Nowe ulepszenia

workbox-strategies

Workbox v6 wprowadza nowy sposób definiowania własnych strategii Workbox przez deweloperów zewnętrznych. Dzięki temu deweloperzy zewnętrzni mogą rozszerzać Workbox w sposób, który w pełni odpowiada ich potrzebom.

Nowa klasa bazowa strategii

W wersji 6 wszystkie klasy strategii Workbox muszą rozszerzać nową klasę bazową Strategy. Wszystkie wbudowane strategie zostały przepisane, aby to umożliwić.

Klasa bazowa Strategy odpowiada za 2 główne kwestie:

  • wywoływanie wywołań zwrotnych cyklu życia wtyczki wspólnych dla wszystkich modułów obsługi strategii (np. gdy się uruchamiają, odpowiadają i kończą działanie);
  • tworzenie instancji „modułu obsługi”, która może zarządzać stanem każdego żądania obsługiwanego przez strategię;

Nowa klasa „handler”

Wcześniej mieliśmy moduły wewnętrzne o nazwach fetchWrapper i cacheWrapper, które (jak sugerują ich nazwy) opakowują różne interfejsy API pobierania i pamięci podręcznej za pomocą punktów zaczepienia w ich cyklu życia. Jest to mechanizm, który obecnie umożliwia działanie wtyczek, ale nie jest on dostępny dla deweloperów.

Nowa klasa „handler”, StrategyHandler, udostępni te metody, dzięki czemu strategie niestandardowe będą mogły wywoływać metody fetch() lub cacheMatch() i automatycznie wywoływać wszystkie wtyczki dodane do instancji strategii.

Ta klasa umożliwiłaby też deweloperom dodawanie własnych niestandardowych wywołań zwrotnych cyklu życia, które mogą być specyficzne dla ich strategii i będą „po prostu działać” z istniejącym interfejsem wtyczki.

Nowy stan cyklu życia wtyczki

We Workboxie w wersji 5 wtyczki są bezstanowe. Oznacza to, że jeśli żądanie dotyczące /index.html wywoła zarówno wywołanie zwrotne requestWillFetch, jak i cachedResponseWillBeUsed, te 2 wywołania zwrotne nie będą mogły się ze sobą komunikować ani nawet nie będą wiedzieć, że zostały wywołane przez to samo żądanie.

W wersji 6 wszystkie wywołania zwrotne wtyczki będą też przekazywać nowy obiekt state. Ten obiekt stanu będzie unikalny dla tego konkretnego obiektu wtyczki i tego konkretnego wywołania strategii (czyli wywołania handle()). Dzięki temu deweloperzy mogą pisać wtyczki, w których jedno wywołanie zwrotne może warunkowo wykonać działanie na podstawie tego, co zrobiło inne wywołanie zwrotne w tej samej wtyczce (np. obliczyć różnicę czasu między uruchomieniem requestWillFetch i fetchDidSucceed lub fetchDidFail).

Nowe wywołania zwrotne cyklu życia wtyczki

Dodano nowe wywołania zwrotne cyklu życia wtyczki, aby umożliwić deweloperom pełne wykorzystanie stanu cyklu życia wtyczki:

  • handlerWillStart: wywoływana przed uruchomieniem logiki modułu obsługi. To wywołanie zwrotne może służyć do ustawiania początkowego stanu modułu obsługi (np. do rejestrowania czasu rozpoczęcia).
  • handlerWillRespond: wywoływana, zanim metoda handle() strategii zwróci odpowiedź. To wywołanie zwrotne może służyć do modyfikowania tej odpowiedzi przed zwróceniem jej do modułu obsługi trasy lub innej niestandardowej logiki.
  • handlerDidRespond: wywoływana po zwróceniu odpowiedzi przez metodę handle() strategii. To wywołanie zwrotne może służyć do rejestrowania ostatecznych szczegółów odpowiedzi, np. po zmianach wprowadzonych przez inne wtyczki.
  • handlerDidComplete: wywoływana po rozliczeniu wszystkich obietnic przedłużenia okresu ważności dodanych do zdarzenia po wywołaniu tej strategii. To wywołanie zwrotne może służyć do raportowania danych, które do obliczenia wymagają zakończenia działania modułu obsługi (np. stan trafienia w pamięci podręcznej, opóźnienie pamięci podręcznej, opóźnienie sieci).
  • handlerDidError: wywoływana, jeśli moduł obsługi nie mógł podać prawidłowej odpowiedzi z żadnego źródła. To wywołanie zwrotne może służyć do dostarczania treści „zastępczych” jako alternatywy dla błędu sieci.

Deweloperzy wdrażający własne strategie niestandardowe nie muszą się martwić o samodzielne wywoływanie tych wywołań zwrotnych – wszystkim zajmuje się nowa klasa podstawowa Strategy.

Dokładniejsze typy TypeScript dla modułów obsługi

Znormalizowano definicje TypeScript dla różnych metod wywołania zwrotnego. Powinno to ułatwić pracę deweloperom, którzy używają TypeScriptu i piszą własny kod do implementowania lub wywoływania modułów obsługi.

workbox-window

Nowa metoda messageSkipWaiting()

Do modułu workbox-window dodano nową metodę messageSkipWaiting(), która upraszcza proces aktywowania „oczekującego” skryptu service worker. To rozwiązanie ma kilka zalet:

  • Wywołuje postMessage() z treścią wiadomości {type: 'SKIP_WAITING'}, która jest de facto standardem i którą skrypt service worker wygenerowany przez Workbox sprawdza, aby aktywować skipWaiting().
  • Wybiera odpowiedni skrypt service worker w stanie „oczekiwania”, do którego ma wysłać tę wiadomość, nawet jeśli nie jest to ten sam skrypt, z którym zarejestrowano workbox-window.

Usunięcie zdarzeń „zewnętrznych” na rzecz właściwości isExternal

Wszystkie zdarzenia „external” w workbox-window zostały usunięte i zastąpione zdarzeniami „normal” z właściwością isExternal ustawioną na true. Dzięki temu deweloperzy, którym zależy na rozróżnieniu, mogą nadal je wykrywać, a deweloperzy, którzy nie muszą tego wiedzieć, mogą zignorować tę właściwość.

Przejrzystszy przepis „Zaproponuj użytkownikom ponowne załadowanie strony”

Dzięki obu tym zmianom można uprościć przepis „Oferowanie użytkownikom ponownego załadowania strony”:

// v6:
<script type="module">
  import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.0.0-alpha.1/workbox-window.prod.mjs';

  if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');

    const showSkipWaitingPrompt = () => {
      // This assumes a hypothetical createUIPrompt() method with
      // onAccept and onReject callbacks:
      const prompt = createUIPrompt({
        onAccept: () => {
          wb.addEventListener('controlling', () => {
            window.location.reload();
          });

          // This will postMessage() to the waiting service worker.
          wb.messageSkipWaiting();
        },

        onReject: () => {
          prompt.dismiss();
        },
      });
    };

    // Listening for externalwaiting is no longer needed.
    wb.addEventListener('waiting', showSkipWaitingPrompt);
    wb.register();
  }
</script>

workbox-routing

Nowy parametr logiczny sameOrigin jest przekazywany do funkcji matchCallback używanej w workbox-routing. Jeśli żądanie dotyczy adresu URL tego samego źródła, ma wartość true, a w przeciwnym razie – false.

Upraszcza to niektóre typowe elementy:

// In v5:
registerRoute(
  ({url}) =>
    url.origin === self.location.origin && url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'})
);

// In v6:
registerRoute(
  ({sameOrigin, url}) => sameOrigin && url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'})
);

matchOptions w workbox-expiration

Możesz teraz ustawić matchOptions w workbox-expiration, który zostanie przekazany jako CacheQueryOptions do podstawowego wywołania cache.delete(). (Większość deweloperów nie musi tego robić).

workbox-precaching

Używa strategii Workbox

Zasób workbox-precaching został przepisany, aby używać zasobu workbox-strategies jako podstawy. Nie powinno to spowodować żadnych zmian powodujących niezgodność i powinno zapewnić lepszą spójność w dłuższej perspektywie w sposobie, w jaki oba moduły uzyskują dostęp do sieci i pamięci podręcznej.

Wstępne buforowanie przetwarza teraz wpisy pojedynczo, a nie zbiorczo.

Zaktualizowaliśmy workbox-precaching, aby żądanie i zapisywanie w pamięci podręcznej dotyczyło tylko jednego wpisu w pliku manifestu wstępnego zapisu w pamięci podręcznej naraz, zamiast próbować żądać i zapisywać w pamięci podręcznej wszystkie wpisy jednocześnie (pozostawiając przeglądarce ustalenie, jak ograniczyć przepustowość).

Powinno to zmniejszyć prawdopodobieństwo wystąpienia błędów net::ERR_INSUFFICIENT_RESOURCES podczas wstępnego buforowania, a także ograniczyć rywalizację o przepustowość między wstępnym buforowaniem a jednoczesnymi żądaniami wysyłanymi przez aplikację internetową.

PrecacheFallbackPlugin ułatwia korzystanie z trybu offline

workbox-precaching zawiera teraz PrecacheFallbackPlugin, który implementuje nową metodę cyklu życia handlerDidError dodaną w wersji 6.

Ułatwia to określenie wstępnie zapisanego w pamięci podręcznej adresu URL jako „zastępczego” dla danej strategii, gdy odpowiedź nie jest dostępna. Wtyczka zajmie się prawidłowym utworzeniem właściwego klucza pamięci podręcznej dla wstępnie zapisanego adresu URL, w tym wszelkich potrzebnych parametrów wersji.

Oto przykład użycia tej metody do zwrócenia wstępnie zapisanego w pamięci podręcznej elementu /offline.html, gdy strategia NetworkOnly nie może wygenerować odpowiedzi na żądanie nawigacji – innymi słowy, do wyświetlenia niestandardowej strony HTML offline:

import {PrecacheFallbackPlugin, precacheAndRoute} from 'workbox-precaching';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

// Ensure that /offline.html is part of your precache manifest!
precacheAndRoute(self.__WB_MANIFEST);

registerRoute(
  ({request}) => request.mode === 'navigate',
  new NetworkOnly({
    plugins: [
      new PrecacheFallbackPlugin({
        fallbackURL: '/offline.html',
      }),
    ],
  })
);

precacheFallback w buforowaniu w czasie działania

Jeśli do utworzenia skryptu service worker używasz generateSW, zamiast pisać go ręcznie, możesz użyć nowej opcji konfiguracji precacheFallback w runtimeCaching, aby osiągnąć ten sam efekt:

{
  // ... other generateSW config options...
  runtimeCaching: [{
    urlPattern: ({request}) => request.mode === 'navigate',
    handler: 'NetworkOnly',
    options: {
      precacheFallback: {
        // This URL needs to be included in your precache manifest.
        fallbackURL: '/offline.html',
      },
    },
  }],
}

Uzyskiwanie pomocy

Spodziewamy się, że większość migracji będzie przebiegać bezproblemowo. Jeśli napotkasz problemy, które nie zostały opisane w tym przewodniku, daj nam znać, zgłaszając problem na GitHubie.