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