Использование Workbox без предварительного кэширования

До сих пор эта документация была посвящена предварительному кэшированию, часто затрагивая инструменты generateSW и injectManifest . Хотя существует множество веских причин для включения логики предварительного кэширования в ваш сервис-воркер, вам не обязательно использовать предварительное кэширование для использования Workbox.

Возможно, вашему проекту требуется только кэширование во время выполнения, или, может быть, вам нужен более чистый способ интеграции API-интерфейсов сервис-воркеров, таких как Web Push . Это случаи, когда вы не захотите использовать инструменты сборки Workbox, и это описано в этой статье.

При использовании упаковщика

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

В корне исходного каталога вашего проекта вы создадите сервис-воркера и будете использовать любые модули Workbox, необходимые вашему приложению. Вот пример без предварительного кэширования, в котором вместо этого настраиваются стратегии кэширования для запросов навигации и изображений в отдельных экземплярах Cache :

// sw.js
import {NetworkFirst, CacheFirst} from 'workbox-strategies';
import {registerRoute, NavigationRoute, Route} from 'workbox-routing';

const navigationRoute = new NavigationRoute(new NetworkFirst({
  cacheName: 'navigations'
}));

const imageAssetRoute = new Route(({request}) => {
  return request.destination === 'image';
}, new CacheFirst({
  cacheName: 'image-assets'
}));

registerRoute(navigationRoute);
registerRoute(imageAssetRoute);

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

веб-пакет

webpack принимает точки входа в своей конфигурации entry . При использовании этого подхода следует учитывать несколько вещей:

  1. Чтобы гарантировать, что ваш сервис-воркер имеет максимально широкую область действия, вам нужно, чтобы он выводился в корень вашего выходного каталога.
  2. Вы не хотите, чтобы у сервис-воркера была версия, так как его обновления будут генерировать новые хэши, что может привести к развертыванию нескольких сервис-воркеров на вашем веб-сайте.

Чтобы удовлетворить вышеуказанные условия, в output.filename можно передать функцию, которая проверяет, является ли текущая обрабатываемая точка входа точкой входа сервис-воркера. В противном случае файлы с версиями записываются в свои обычные места назначения.

// webpack.config.js
import process from 'process';

const isProd = process.env.NODE_ENV === 'production';

export default {
  mode: isProd ? 'production' : 'development',
  context: process.cwd(),
  entry: {
    // Service worker entry point:
    sw: './src/sw.js',
    // Application entry point:
    app: './src/index.js'
  },
  output: {
    filename: ({runtime}) => {
      // Check if the current filename is for the service worker:
      if (runtime === 'sw') {
        // Output a service worker in the root of the dist directory
        // Also, ensure the output file name doesn't have a hash in it
        return '[name].js';
      }

      // Otherwise, output files as normal
      return 'js/[name].[contenthash:8].js';
    },
    path: './dist',
    publicPath: '/',
    clean: true
  }
};

объединение

Накопительный пакет аналогичен ситуации с веб-пакетом, за исключением того, что несколько точек входа указываются как отдельные объекты конфигурации, экспортируемые в массив:

// rollup.config.js
import { nodeResolve } from '@rollup/plugin-node-resolve';
import replace from '@rollup/plugin-replace';

// Plugins common to both entry points
const plugins = [
  nodeResolve(),
];

export default [
  // Application entry point
  {
    input: './src/index.js',
    output: {
      dir: './dist/js',
      format: 'esm'
    },
    plugins
  },
  // Service worker entry point
  {
    input: './src/sw.js',
    output: {
      file: './dist/sw.js',
      format: 'iife'
    },
    plugins: [
      ...plugins,
      // This @rollup/plugin-replace instance replaces process.env.NODE_ENV
      // statements in the Workbox libraries to match your current environment.
      // This changes whether logging is enabled ('development') or disabled ('production').
      replace({
        'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production')
      })
    ]
  }
];

эсбилд

esbuild предлагает простой интерфейс командной строки:

npx esbuild ./src/sw.js --bundle --minify --outfile=./dist/sw.js

esbuild позаботится о замене процесса.env.NODE_ENV на «разработку» по умолчанию или на «производство», если включена минификация.

Без упаковщика с использованием workbox-sw

Ваш проект может даже не использовать сборщик. workbox-sw может загрузить для вас среду выполнения Workbox из CDN внутри вашего сервис-воркера и без этапа сборки, если вы импортируете ее с помощью importScripts :

// sw.js

// Imports Workbox from the CDN. Note that "6.2.0" of the URL
// is the version of the Workbox runtime.
importScripts('https://storage.googleapis.com/workbox-cdn/releases/6.2.0/workbox-sw.js');

const navigationRoute = new workbox.routing.NavigationRoute(new workbox.strategies.NetworkFirst({
  cacheName: 'navigations'
}));

const imageAssetRoute = new workbox.routing.Route(({request}) => {
  return request.destination === 'image';
}, new workbox.strategies.CacheFirst({
  cacheName: 'image-assets'
}));

workbox.routing.registerRoute(navigationRoute);
workbox.routing.registerRoute(staticAssetRoute);

Если перспектива загрузки среды выполнения Workbox из CDN не кажется вам радужной, можно использовать workbox-sw с локальными URL-адресами .

Заключение

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