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

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

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

ядро рабочего ящика

Метод skipWaiting() в workbox-core больше не будет добавлять обработчик install и эквивалентен простому вызову self.skipWaiting() .

С этого момента вместо этого используйте self.skipWaiting() , поскольку в Workbox v7, скорее всего skipWaiting() будет удален.

предварительное кэширование рабочего ящика

  • HTML-документы с перекрестным происхождением для URL-адресов, соответствующих перенаправлению HTTP, больше нельзя использовать для удовлетворения запроса навигации с помощью workbox-precaching . Этот сценарий вообще необычен.
  • Параметр запроса URL-адреса fbclid теперь игнорируется workbox-precaching при поиске предварительно кэшированного ответа для данного запроса.
  • Конструктор PrecacheController теперь принимает в качестве параметра объект с определенными свойствами, а не строку. Этот объект поддерживает следующие свойства: cacheName (служит той же цели, что и строка, переданная конструктору в версии 5), plugins (заменяющий метод addPlugins() из версии 5) и fallbackToNetwork (заменяющий аналогичный параметр, который был передан в createHandler() и createHandlerBoundToURL() в версии 5).
  • Методы install() и activate() PrecacheController теперь принимают ровно один параметр, который должен быть установлен в соответствующий InstallEvent или ActivateEvent соответственно.
  • Метод addRoute() был удален из PrecacheController . Вместо него можно использовать новый класс PrecacheRoute для создания маршрута, который затем можно зарегистрировать.
  • Метод precacheAndRoute() был удален из PrecacheController . (Он по-прежнему существует как статический вспомогательный метод, экспортируемый модулем workbox-precaching .) Он был удален, поскольку вместо него можно использовать PrecacheRoute .
  • Метод createMatchCalback() был удален из PrecacheController . Вместо этого можно использовать новый PrecacheRoute .
  • Метод createHandler() был удален из PrecacheController . Вместо этого для обработки запросов можно использовать свойство strategy объекта PrecacheController .
  • Статический экспорт createHandler() уже удален из модуля workbox-precaching . Вместо него разработчикам следует создать экземпляр PrecacheController и использовать его свойство strategy .
  • Маршрут, зарегистрированный с помощью precacheAndRoute() теперь является «настоящим» маршрутом, который использует под капотом класс Router workbox-routing . Это может привести к другому порядку оценки ваших маршрутов, если вы чередуете вызовы registerRoute() и precacheAndRoute() .

маршрутизация рабочего ящика

Метод setDefaultHandler() теперь принимает необязательный второй параметр, соответствующий методу HTTP, к которому он применяется, по умолчанию — 'GET' .

  • Если вы используете setDefaultHandler() и все ваши запросы GET , никаких изменений вносить не нужно.
  • Если у вас есть запросы, отличные от GET ( POST , PUT и т. д.), setDefaultHandler() больше не будет вызывать совпадение этих запросов.

Конфигурация сборки

Опция mode для режимов getManifest и injectManifest в workbox-build и workbox-cli не предполагалась для поддержки и была удалена. Это не относится к workbox-webpack-plugin , который поддерживает mode в своем плагине InjectManifest .

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

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

Новые улучшения

стратегии рабочего ящика

Workbox v6 предоставляет сторонним разработчикам новый способ определять свои собственные стратегии Workbox. Это гарантирует, что сторонние разработчики смогут расширять Workbox способами, полностью отвечающими их потребностям.

Базовый класс новой стратегии

В версии 6 все классы стратегий Workbox должны расширять новый базовый класс Strategy . Все встроенные стратегии были переписаны для поддержки этой возможности.

Базовый класс Strategy отвечает за две основные вещи:

  • Вызов обратных вызовов жизненного цикла плагина, общих для всех обработчиков стратегии (например, когда они запускаются, отвечают и заканчиваются).
  • Создание экземпляра «обработчика», который может управлять состоянием каждого отдельного запроса, обрабатываемого стратегией.

Новый класс «обработчик»

Ранее у нас были внутренние модули под названием fetchWrapper cacheWrapper , которые (как следует из их названия) оборачивают различные API-интерфейсы выборки и кэширования с помощью перехватчиков в их жизненный цикл. Это механизм, который в настоящее время позволяет плагинам работать, но он не доступен разработчикам.

Новый класс «обработчика», StrategyHandler , будет предоставлять эти методы, чтобы пользовательские стратегии могли вызывать fetch() или cacheMatch() и автоматически вызывать любые плагины, которые были добавлены в экземпляр стратегии.

Этот класс также позволит разработчикам добавлять свои собственные обратные вызовы жизненного цикла, которые могут быть специфичными для их стратегий, и они будут «просто работать» с существующим интерфейсом плагина.

Новое состояние жизненного цикла плагина

В Workbox v5 плагины не имеют состояния. Это означает, что если запрос на /index.html запускает оба обратных вызова requestWillFetch и cachedResponseWillBeUsed , эти два обратных вызова не имеют возможности взаимодействовать друг с другом или даже знать, что они были вызваны одним и тем же запросом.

В версии 6 всем обратным вызовам плагинов также будет передан новый объект state . Этот объект состояния будет уникальным для этого конкретного объекта плагина и этого конкретного вызова стратегии (т. е. вызова handle() ). Это позволяет разработчикам писать плагины, в которых один обратный вызов может условно делать что-то на основе того, что сделал другой обратный вызов в том же плагине (например, вычислять разницу во времени между запуском requestWillFetch и fetchDidSucceed или fetchDidFail ).

Обратные вызовы жизненного цикла нового плагина

Были добавлены новые обратные вызовы жизненного цикла плагина, чтобы позволить разработчикам в полной мере использовать состояние жизненного цикла плагина:

  • handlerWillStart : вызывается перед запуском какой-либо логики обработчика. Этот обратный вызов можно использовать для установки начального состояния обработчика (например, записи времени начала).
  • handlerWillRespond : вызывается перед тем, как метод handle() стратегии возвращает ответ. Этот обратный вызов можно использовать для изменения этого ответа перед его возвратом обработчику маршрута или другой пользовательской логике.
  • handlerDidRespond : вызывается после того, как метод handle() стратегии возвращает ответ. Этот обратный вызов можно использовать для записи любых окончательных деталей ответа, например, после изменений, внесенных другими плагинами.
  • handlerDidComplete : вызывается после того, как все обещания продления срока действия , добавленные к событию в результате вызова этой стратегии, выполнены. Этот обратный вызов можно использовать для отчета о любых данных, которым необходимо дождаться завершения работы обработчика для вычислений (например, статус попадания в кэш, задержка кэша, задержка сети).
  • handlerDidError : вызывается, если обработчик не смог предоставить действительный ответ из любого источника. Этот обратный вызов можно использовать для предоставления «резервного» контента в качестве альтернативы сетевой ошибке.

Разработчикам, реализующим свои собственные стратегии, не нужно беспокоиться о самостоятельном вызове этих обратных вызовов; все это обрабатывается новым базовым классом Strategy .

Более точные типы TypeScript для обработчиков.

Определения TypeScript для различных методов обратного вызова были нормализованы. Это должно улучшить работу разработчиков, которые используют TypeScript и пишут собственный код для реализации или вызова обработчиков.

окно рабочего ящика

Новый метод messageSkipWaiting()

В модуль workbox-window был добавлен новый метод messageSkipWaiting() , чтобы упростить процесс сообщения «ожидающему» сервисному работнику об активации. Это предлагает некоторые улучшения:

  • Он вызывает postMessage() с де-факто стандартным телом сообщения {type: 'SKIP_WAITING'} , которое проверяет сервисный работник, созданный Workbox, для запуска skipWaiting() .
  • Он выбирает правильного «ожидающего» сервис-воркера для отправки этого сообщения, даже если это не тот же самый сервис-воркер, у которого было зарегистрировано workbox-window .

Удаление «внешних» событий в пользу свойства isExternal.

Все «внешние» события в workbox-window были удалены вместо «обычных» событий со свойством isExternal , установленным в true . Это позволяет разработчикам, которым важно это различие, обнаружить его, а разработчики, которым это не нужно знать, могут игнорировать это свойство.

Очиститель рецепта «Предложить пользователям перезагрузку страницы»

Благодаря обоим вышеизложенным изменениям рецепт «Предложить пользователям перезагрузку страницы» можно упростить:

MULTI_LINE_CODE_PLACEHOLDER_0

маршрутизация рабочего ящика

Новый логический параметр sameOrigin передается в функцию matchCallback , используемую в workbox-routing . Для него установлено значение true , если запрос относится к URL-адресу того же источника, и значение false в противном случае.

Это упрощает некоторые общие шаблоны:

MULTI_LINE_CODE_PLACEHOLDER_1

matchOptions в рабочем поле-expiration

Теперь вы можете установить matchOptions в workbox-expiration , который затем будет передан как CacheQueryOptions в базовый вызов cache.delete() . (Большинству разработчиков это не понадобится.)

предварительное кэширование рабочего ящика

Использует стратегии рабочего ящика

workbox-precaching был переписан для использования в качестве основы workbox-strategies . Это не должно привести к каким-либо критическим изменениям и должно привести к лучшей долгосрочной согласованности в том, как два модуля получают доступ к сети и кешу.

Предварительное кэширование теперь обрабатывает записи по одной, а не массово.

workbox-precaching был обновлен таким образом, что одновременно запрашивается и кэшируется только одна запись в манифесте precache, вместо того, чтобы пытаться запросить и кэшировать их все одновременно (оставляя браузеру возможность выяснить, как регулировать).

Это должно снизить вероятность ошибок net::ERR_INSUFFICIENT_RESOURCES при предварительном кэшировании, а также уменьшить конфликты за полосу пропускания между предварительным кэшированием и одновременными запросами, выполняемыми веб-приложением.

PrecacheFallbackPlugin позволяет упростить откат в автономном режиме.

workbox-precaching теперь включает в себя PrecacheFallbackPlugin , который реализует новый метод жизненного цикла handlerDidError , добавленный в v6.

Это позволяет легко указать предварительно кэшированный URL-адрес в качестве «резервного» для данной стратегии, если в противном случае ответ был бы недоступен. Плагин позаботится о правильном создании правильного ключа кэша для предварительно кэшированного URL-адреса, включая любые необходимые параметры версии.

Вот пример его использования для ответа с предварительно кэшированным /offline.html , когда стратегия NetworkOnly не может сгенерировать ответ на запрос навигации — другими словами, отображение пользовательской автономной HTML-страницы:

MULTI_LINE_CODE_PLACEHOLDER_2

precacheFallback при кэшировании во время выполнения

Если вы generateSW для создания сервис-воркера вместо того, чтобы писать его вручную, вы можете использовать новую опцию конфигурации precacheFallback в runtimeCaching , чтобы добиться того же:

{
  // ... 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',
      },
    },
  }],
}

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

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