Один модуль 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 .