Расширение Workbox сторонними модулями

Workbox предоставляет гибкую архитектуру для расширения возможностей сервис-воркеров с помощью сторонних модулей. Сторонние модули позволяют добавлять новые стратегии кеширования, интеграцию с аналитикой, обработку специальных событий и многое другое. Подключение сторонних модулей может выполняться как через npm, так и через CDN, в зависимости от требований проекта.

import { registerRoute } from 'workbox-routing';
import { CacheFirst } from 'workbox-strategies';
import myCustomModule from 'my-workbox-plugin';

В этом примере myCustomModule является сторонним плагином, который можно интегрировать с любой стратегией кеширования Workbox.


Структура стороннего плагина

Сторонний модуль для Workbox обычно реализуется в виде объекта, содержащего методы-перехватчики жизненного цикла запроса и ответа:

  • cacheWillUpdate — вызывается перед сохранением ресурса в кэш.
  • cacheDidUpdate — вызывается после обновления кэша.
  • fetchDidFail — вызывается при ошибке запроса.
  • requestWillFetch — позволяет модифицировать исходный запрос перед отправкой на сервер.
  • handlerDidError — перехватывает ошибки, возникающие в стратегии обработки запроса.

Пример простого плагина, логирующего все обновления кэша:

const logCachePlugin = {
  cacheDidUpdate: async ({ cacheName, request, oldResponse, newResponse }) => {
    console.log(`Кэш ${cacheName} обновлён: ${request.url}`);
  }
};

registerRoute(
  ({ request }) => request.destination === 'image',
  new CacheFirst({
    cacheName: 'images-cache',
    plugins: [logCachePlugin]
  })
);

Интеграция с существующими стратегиями

Workbox позволяет использовать сторонние плагины совместно с встроенными стратегиями:

  • CacheFirst — сначала проверяет кэш, если ресурса нет, делает запрос к сети.
  • NetworkFirst — сначала обращается к сети, если сеть недоступна, использует кэш.
  • StaleWhileRevalidate — возвращает кэш сразу и параллельно обновляет его с сервера.

Сторонние модули подключаются через массив plugins, что обеспечивает модульность и расширяемость:

import analyticsPlugin from 'workbox-analytics-plugin';

registerRoute(
  ({ url }) => url.pathname.startsWith('/api/'),
  new NetworkFirst({
    cacheName: 'api-cache',
    plugins: [analyticsPlugin]
  })
);

Создание собственного плагина

Для создания собственного плагина важно реализовать хотя бы один из методов жизненного цикла. Можно комбинировать несколько методов для сложной логики обработки:

class CustomLoggingPlugin {
  async requestWillFetch({ request }) {
    console.log(`Запрос к: ${request.url}`);
    return request;
  }

  async fetchDidFail({ originalRequest }) {
    console.warn(`Ошибка при загрузке: ${originalRequest.url}`);
  }
}

registerRoute(
  ({ request }) => request.destination === 'script',
  new NetworkFirst({
    cacheName: 'scripts-cache',
    plugins: [new CustomLoggingPlugin()]
  })
);

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


Поддержка асинхронных операций

Методы сторонних плагинов могут быть асинхронными, что важно для интеграции с IndexedDB, внешними сервисами аналитики или другими источниками данных. Асинхронные методы возвращают Promise, который Workbox ожидает перед завершением операции:

const asyncPlugin = {
  async cacheWillUpdate({ response }) {
    if (!response.ok) return null;
    await sendLogToServer(response.url);
    return response;
  }
};

Совместимость и конфликты

При использовании нескольких сторонних модулей важно учитывать порядок подключения и возможные конфликты. Методы плагинов вызываются в порядке их подключения, и если один плагин возвращает null, последующие методы могут не сработать. Рекомендуется:

  • Разделять логику плагинов на отдельные модули.
  • Не перезаписывать объекты запроса и ответа без необходимости.
  • Обрабатывать исключения внутри каждого плагина, чтобы не прерывать цепочку.

Подключение через CDN

Для проектов без сборщика модулей можно подключать сторонние плагины через CDN, используя глобальные объекты Workbox:

<script src="https://storage.googleapis.com/workbox-cdn/releases/6.7.0/workbox-sw.js"></script>
<script src="https://cdn.example.com/my-workbox-plugin.js"></script>
<script>
  const myPlugin = window.MyWorkboxPlugin;
  workbox.routing.registerRoute(
    ({ request }) => request.destination === 'image',
    new workbox.strategies.CacheFirst({
      cacheName: 'images-cache',
      plugins: [myPlugin]
    })
  );
</script>

Такой подход особенно удобен для статических сайтов или быстрых прототипов, где сборка через Webpack или Vite не используется.


Заключение о расширяемости

Сторонние модули в Workbox обеспечивают гибкость, позволяя добавлять новые возможности без изменения ядра библиотеки. Они интегрируются через стандартные стратегии и методы жизненного цикла, поддерживают асинхронность и легко комбинируются между собой. Правильное использование плагинов повышает устойчивость сервис-воркеров, оптимизирует кэширование и расширяет функционал приложений на JavaScript.