Миграция с Workbox v4 на v5,Миграция с Workbox v4 на v5

Это руководство посвящено критическим изменениям, представленным в Workbox v5, и содержит примеры того, какие изменения необходимо внести при обновлении с Workbox v4.

Критические изменения

Классы плагинов переименованы

Ряд пакетов Workbox v4 включал классы с именем Plugin . В версии 5 эти классы были переименованы в соответствии с идентификатором пакета шаблона + Plugin :

  • BackgroundSyncPlugin
  • BroadcastUpdatePlugin
  • CacheableResponsePlugin
  • ExpirationPlugin
  • RangeRequestsPlugin

Это переименование применяется независимо от того, используете ли вы классы через импорт модулей или через пространства имен workbox.* .

Точка замены манифеста Precache по умолчанию

Ранее при использовании одного из инструментов сборки в режиме «внедрения манифеста» ваш исходный рабочий файл службы проверялся на наличие precacheAndRoute([]) , при этом этот пустой массив [] использовался в качестве заполнителя для точки, в которой предварительное кэширование манифест был введен.

В Workbox v5 изменилась логика замены, и теперь в качестве точки внедрения по умолчанию используется self.__WB_MANIFEST .

// v4:
precacheAndRoute([]);

// v5:
precacheAndRoute(self.__WB_MANIFEST);

Как указано в этом обсуждении , мы считаем, что это изменение упрощает работу и одновременно дает разработчикам больше контроля над тем, как внедренный манифест используется в коде пользовательского работника службы. При необходимости вы можете изменить эту строку замены с помощью параметра конфигурации injectionPoint .

Два варианта, которые ранее поддерживались для маршрутов навигации, blacklist и whitelist были переименованы в denylist и allowlist .

workbox-routing ранее поддерживал метод registerNavigationRoute() , который «под капотом» делал две вещи:

  1. Обнаружено, имело ли данное событие fetch mode 'navigate' .
  2. Если да, ответьте на этот запрос, используя содержимое ранее кэшированного, жестко запрограммированного URL-адреса, независимо от URL-адреса, по которому осуществляется переход.

Это распространенный шаблон, используемый при реализации архитектуры App Shell .

Второй шаг — генерация ответа путем чтения из кэша — выходит за рамки того, что мы считаем обязанностями workbox-routing . Вместо этого мы рассматриваем это как функциональность, которая должна быть частью workbox-precaching через новый метод createHandlerBoundToURL() . Этот новый метод может работать рука об руку с существующим классом NavigationRoute в workbox-routing для реализации той же логики.

Если вы используете опцию navigateFallback в одном из режимов создания ПО инструмента сборки, то переключение произойдет автоматически. Если вы ранее настроили параметры navigateFallbackBlacklist или navigateFallbackWhitelist , измените их на navigateFallbackDenylist или navigateFallbackAllowlist соответственно.

Если вы используете режим «внедрения манифеста» или просто пишете сервис-воркера самостоятельно, а ваш сервис-воркер Workbox v4 напрямую вызывает registerNavigationRoute() , вам придется внести изменения в свой код, чтобы получить эквивалентное поведение.

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

Вам больше не нужно вызывать getCacheKeyForURL() , поскольку createHandlerBoundToURL() позаботится об этом за вас.

Удаление makeRequest() из стратегий рабочей области

Вызов makeRequest() в основном эквивалентен вызову handle() в одном из классов workbox-strategy . Различия между этими двумя методами были настолько незначительными, что сохранять оба метода не имело смысла. Разработчики, вызвавшие makeRequest() , должны иметь возможность переключиться на использование 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});

В версии 5 handle() рассматривает request как обязательный параметр и не возвращается к использованию event.request . Убедитесь, что вы передаете действительный запрос при вызове handle() .

workbox-broadcast-update Всегда использует postMessage()

В версии 4 библиотека workbox-broadcast-update по умолчанию использовала API широковещательного канала для отправки сообщений, если он поддерживался, и возвращалась к использованию postMessage() только тогда, когда широковещательный канал не поддерживался.

Мы поняли, что необходимость прослушивать два потенциальных источника входящих сообщений слишком усложняет написание клиентского кода. Кроме того, в некоторых браузерах вызовы postMessage() от сервисного работника, отправленные на клиентские страницы, автоматически буферизуются до тех пор, пока не будет настроен прослушиватель событий message . В API широковещательного канала буферизация отсутствует, а широковещательные сообщения просто удаляются, если они отправлены до того, как клиентская страница будет готова их принять.

По этим причинам мы изменили workbox-broadcast-update , чтобы всегда использовать postMessage() в версии 5. Сообщения отправляются одно за другим на все клиентские страницы в пределах текущего сервис-воркера.

Чтобы приспособиться к этому новому поведению, вы можете удалить любой код, который у вас был на клиентских страницах, которые создавали экземпляры BroadcastChannel , и вместо этого настроить прослушиватель событий message в 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 ...
  }
});

Пользователям workbox-window не нужно вносить какие-либо изменения, поскольку его внутренняя логика была обновлена ​​для прослушивания вызовов postMessage() .

Для инструментов сборки требуется Node.js v8 или выше

Версии Node.js до v8 больше не поддерживаются для workbox-webpack-plugin , workbox-build или workbox-cli . Если вы используете версию Node.js до 8, обновите среду выполнения до поддерживаемой версии .

workbox-webpack-plugin Требуется webpack v4 или выше.

Если вы используете workbox-webpack-plugin , обновите настройки веб-пакета , чтобы использовать как минимум веб-пакет v4.

Обновление параметров инструмента сборки

Ряд параметров конфигурации workbox-build , workbox-cli и workbox-webpack-plugin больше не поддерживаются. Например, generateSW всегда создаст для вас локальный пакет среды выполнения Workbox, поэтому опция importWorkboxFrom больше не имеет смысла.

Список поддерживаемых опций можно найти в документации соответствующего инструмента.

УдалениеgenerateSWSString из сборки рабочего ящика

Режим generateSWString был удален из workbox-build . Мы ожидаем, что влияние этого будет минимальным, поскольку оно в основном использовалось внутри workbox-webpack-plugin .

Дополнительные изменения

Использование импорта модулей

Хотя это изменение является а) необязательным и б) технически возможным при использовании Workbox v4, самое большое изменение, которое мы ожидаем при переходе на v5, — это модель, в которой вы создаете свой собственный встроенный сервис-воркер путем импорта модулей Workbox. Этот подход является альтернативой вызову importScripts('/path/to/workbox-sw.js') в верхней части вашего сервис-воркера и использованию Workbox через пространство имен workbox.* .

Если вы используете один из инструментов сборки ( workbox-webpack-plugin , workbox-build , workbox-cli ) в режиме «генерации ПО», то это изменение произойдет автоматически. Все эти инструменты будут выводить локальный пользовательский пакет среды выполнения Workbox вместе с фактическим кодом, необходимым для реализации логики вашего сервис-воркера. В этом сценарии больше нет зависимости от workbox-sw или CDN-копии Workbox. В зависимости от значения вашей конфигурации inlineWorkboxRuntime среда выполнения Workbox будет либо разделена на отдельный файл, который должен быть развернут вместе с вашим сервис-воркером (если установлено значение false , которое является значением по умолчанию), либо включена встроенно вместе с логикой сервис-воркера ( если установлено значение true ).

Если вы используете инструменты сборки в режиме «внедрения манифеста» или вообще не используете инструменты сборки Workbox, вы можете узнать больше о создании собственного пакета среды выполнения Workbox в существующем документе Использование бандлеров (webpack/Rollup) с помощью Руководство по рабочему ящику .

Документация и примеры для версии 5 написаны с учетом синтаксиса импорта модуля, хотя пространство имен workbox.* будет по-прежнему поддерживаться в Workbox v5.

Чтение предварительно кэшированных ответов

Некоторым разработчикам необходимо читать предварительно кэшированные ответы непосредственно из кеша, а не неявно использовать их с помощью метода precacheAndRoute() . Обычным шаблоном в версии 4 было бы сначала получить ключ кэша, специфичный для текущей версии предварительно кэшированного ресурса, а затем передать этот ключ вместе с именем кэша предварительного кэша в caches.match() , чтобы получить Response .

Чтобы упростить этот процесс, workbox-precaching в версии 5 поддерживает новый эквивалентный метод 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

В v5 библиотеки времени выполнения Workbox написаны на TypeScript . Хотя мы продолжим публиковать перекомпилированные модули и пакеты JavaScript для разработчиков, которые не приняли TypeScript, если вы используете TypeScript, вы должны получить выгоду от точной и всегда актуальной информации о типах непосредственно из проекта Workbox.

Пример миграции

Этот коммит иллюстрирует довольно сложную миграцию со встроенными комментариями. Он использует Rollup для включения пользовательской среды выполнения Workbox в конечный сервис-воркер вместо загрузки среды выполнения из CDN.

Хотя здесь не описаны все критические изменения, здесь представлены события до и после обновления одного файла Service Worker с версии 4 до версии 5, включая переход на TypeScript.

Получать помощь

Мы ожидаем, что большинство миграций будут простыми. Если у вас возникнут проблемы, не описанные в этом руководстве, сообщите нам об этом, открыв проблему на GitHub.