Это руководство посвящено критическим изменениям, представленным в 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()
, который «под капотом» делал две вещи:
- Обнаружено, имело ли данное событие
fetch
mode
'navigate'
. - Если да, ответьте на этот запрос, используя содержимое ранее кэшированного, жестко запрограммированного 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()
. Обычным шаблоном в v4 было бы сначала получить ключ кэша, специфичный для текущей версии предварительно кэшированного ресурса, а затем передать этот ключ вместе с именем кэша предварительного кэша в 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.