Использование рабочего окна-окна

Один модуль Workbox, который еще не получил широкого освещения в этой документации, — это workbox-window , который представляет собой набор модулей, предназначенных для запуска в window . Цели этого модуля:

  • Упростить регистрацию и обновления Service Worker, помогая разработчикам определять критические моменты жизненного цикла Service Worker , что упрощает реагирование в такие моменты.
  • Чтобы разработчики не допускали типичных ошибок, таких как регистрация сервисного работника в неправильной области.
  • Чтобы упростить обмен сообщениями между window и областью Service Worker .

Импорт и использование workbox-window

Экспорт, который вы будете использовать чаще всего из workbox-window — это класс Workbox , который вы можете импортировать в Node или из CDN на веб-странице.

Создание локального пакета

Если ваша цепочка инструментов включает в себя сборщик, такой как webpack или Rollup , вы можете связать workbox-window локально.

Сначала установите workbox-window как производственную зависимость вашего приложения:

npm install workbox-window --save

Затем в JavaScript вашего приложения вы можете import класс Workbox из workbox-window :

<script type="module">
import {Workbox} from 'workbox-window';

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

  wb.register();
}
</script>

Хотя workbox-window довольно маленькое, вы можете отделить его от основной логики приложения вашего веб-сайта с помощью динамического import , что может уменьшить размер основного пакета вашей страницы:

<script type="module">
if ('serviceWorker' in navigator) {
  const {Workbox} = await import('workbox-window');

  const wb = new Workbox('/sw.js');
  wb.register();
}
</script>

Использование CDN

Хотя это и не рекомендуемый подход, более простой способ использования workbox-window — импортировать его из CDN:

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

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

    wb.register();
  }
</script>

Вы заметите, что элемент <script> в приведенном выше примере использует атрибут type="module" . Это необходимо, если вы хотите использовать статические операторы import в браузере без этапа сборки. Все основные браузеры, поддерживающие сервис-воркеры, также поддерживают модули JavaScript, поэтому можно использовать этот код в любом браузере, поскольку старые браузеры будут игнорировать элементы <script> со значением атрибута type "module" .

Регистрация сервис-воркера

Регистрация сервисного работника с помощью workbox-window выполняется с помощью метода register класса Workbox следующим образом:

import {Workbox} from 'workbox-window';

const wb = new Workbox('/sw.js');
wb.register();

Может показаться, что это то же самое, что зарегистрировать сервис-воркера самостоятельно с помощью navigator.serviceWorker.register . Однако Workbox.register обеспечивает ожидание события load window перед регистрацией сервисного работника. Это желательно в ситуациях, когда используется предварительное кэширование, чтобы можно было избежать конфликтов за полосу пропускания, которые могут задержать запуск страницы.

Взаимодействие между window и областью сервис-воркера

Сервис-воркеры имеют собственную область действия, отдельную от window , и имеют доступ только к подмножеству API, доступных в window . Однако связь между window и сервис-воркером возможна. workbox-window упрощает связь между двумя областями с помощью метода messageSW модуля workbox-window .

Workbox использует определенный формат сообщений — это объект со следующими свойствами:

  • type — обязательная уникальная строка, идентифицирующая сообщение. Формат должен быть в верхнем регистре с подчеркиванием, разделяющим слова (например, CACHE_URLS ).
  • meta — это необязательная строка, представляющая имя пакета Workbox, отправляющего сообщение, и обычно опускается.
  • payload — это необязательный параметр, представляющий данные, которые вы хотите отправить. Это может быть любой тип данных.

Ниже приведен пример того, как работает messageSW , начиная с кода вашего сервис-воркера:

// sw.js
const SW_VERSION = '1.0.0';

self.addEventListener('message', (event) => {
  if (event.data.type === 'GET_VERSION') {
    event.ports[0].postMessage(SW_VERSION);
  }
});

А затем следующий код на вашей веб-странице:

const wb = new Workbox('/sw.js');
wb.register();

const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);

Существует множество случаев, когда взаимодействие между Service Worker и window может быть полезным, например, уведомление пользователя о доступности обновления Service Worker . Этот рецепт основан на специальном вспомогательном методе self.skipWaiting под названием messageSkipWaiting , который отправляет сообщение со значением type SKIP_WAITING .