ワークボックス SW

workbox-sw モジュールは、Workbox モジュールの起動と実行を非常に簡単にする方法を提供し、Workbox モジュールの読み込みを簡素化し、いくつかの単純なヘルパー メソッドを提供します。

workbox-sw は、CDN を介して使用することも、独自のサーバー上のワークボックス ファイルと一緒に使用することもできます。

CDN 経由で Workbox SW を使用する

このモジュールの使用を開始する最も簡単な方法は、CDN を使用することです。必要な操作は、以下を Service Worker に追加することだけです。

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

これにより、Service Worker に workbox 名前空間が設定され、すべての Workbox モジュールにアクセスできるようになります。

workbox.precaching.*
workbox.routing.*
etc

追加のモジュールを使い始めると、魔法のような効果があります。

モジュールを初めて参照する場合、workbox-sw はこれを検出し、モジュールを読み込み、利用可能にします。これは DevTools の [Network]タブで確認できます

DevTools でのワークボックス ライブラリの読み込み

これらのファイルはブラウザによってキャッシュに保存され、今後オフラインで使用できるようになります。

CDN の代わりにローカル ワークボックス ファイルを使用する

CDN を使用したくない場合は、独自のドメインでホストされている Workbox ファイルに切り替えるのが簡単です。

最も簡単な方法は、workbox-clicopyLibraries コマンドでファイルを取得し、modulePathPrefix 構成オプションを使用して workbox-sw にファイルの場所を指定することです。

ファイルを /third_party/workbox-vX.Y.Z/ に配置する場合は、次のように使用します。

importScripts('/third_party/workbox-vX.Y.Z/workbox-sw.js');

workbox.setConfig({
  modulePathPrefix: '/third_party/workbox-vX.Y.Z/',
});

非同期インポートを避ける

内部的には、新しいモジュールを初めて読み込む場合は、対応する JavaScript ファイルへのパス(CDN でホストされているか、ローカル URL 経由)を指定して importScripts() を呼び出します。いずれの場合も、重要な制限が適用されます。importScripts() への暗黙的な呼び出しは、Service Worker の install ハンドラ内でのみ、または Service Worker スクリプトの同期的な初回実行中にのみ行われます。

この制限への違反を回避するため、イベント ハンドラや非同期関数の外部にあるさまざまな workbox.* 名前空間を参照することをおすすめします。

たとえば、次のようなトップレベルの Service Worker コードは問題ありません。

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

// This will work!
workbox.routing.registerRoute(
  ({request}) => request.destination === 'image',
  new workbox.strategies.CacheFirst()
);

しかし、Service Worker の別の場所で workbox.strategies を参照していない場合、次のコードは問題となる可能性があります。

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

self.addEventListener('fetch', event => {
  if (event.request.url.endsWith('.png')) {
    // Oops! This causes workbox-strategies.js to be imported inside a fetch handler,
    // outside of the initial, synchronous service worker execution.
    const cacheFirst = new workbox.strategies.CacheFirst();
    event.respondWith(cacheFirst.handle({request: event.request}));
  }
});

この制限に違反するコードを記述する必要がある場合は、workbox.loadModule() メソッドを使用して、イベント ハンドラの外部で importScripts() 呼び出しを明示的にトリガーできます。

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

// This will trigger the importScripts() for workbox.strategies and its dependencies:
workbox.loadModule('workbox-strategies');

self.addEventListener('fetch', event => {
  if (event.request.url.endsWith('.png')) {
    // Referencing workbox.strategies will now work as expected.
    const cacheFirst = new workbox.strategies.CacheFirst();
    event.respondWith(cacheFirst.handle({request: event.request}));
  }
});

または、イベント ハンドラの外で関連する名前空間への参照を作成し、その参照を後で使用することもできます。

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

// This will trigger the importScripts() for workbox.strategies and its dependencies:
const {strategies} = workbox;

self.addEventListener('fetch', event => {
  if (event.request.url.endsWith('.png')) {
    // Using the previously-initialized strategies will work as expected.
    const cacheFirst = new strategies.CacheFirst();
    event.respondWith(cacheFirst.handle({request: event.request}));
  }
});

デバッグビルドまたは本番環境ビルドの強制使用

すべての Workbox モジュールには、ロギングと追加の型チェックを含むデバッグビルドと、ロギングと型チェックを削除する製品版ビルドの 2 つのビルドがあります。

デフォルトでは、workbox-sw は localhost 上のサイトのデバッグビルドを使用しますが、それ以外のオリジンでは本番環境ビルドを使用します。

デバッグビルドまたは製品版ビルドを強制的に実行する場合は、debug 構成オプションを設定します。

workbox.setConfig({
  debug: true,
});

workbox-sw を使用するように import ステートメントを使用してコードを変換する

workbox-sw を使用して Workbox を読み込む場合、すべての Workbox パッケージにはグローバルな workbox.* 名前空間を介してアクセスします。

workbox-sw を使用するように変換する import ステートメントを使用するコードサンプルがある場合、必要な作業は、workbox-sw を読み込み、すべての import ステートメントをグローバル名前空間でそれらのモジュールを参照するローカル変数に置き換えることだけです。

これは、npm に公開されたすべての Workbox Service Worker パッケージが、名前の camelCase バージョンを介してグローバル workbox Namespace で使用できるためです(たとえば、workbox-precaching npm パッケージからエクスポートされたすべてのモジュールは workbox.precaching.* にあります)。また、workbox-background-sync npm パッケージからエクスポートされたすべてのモジュールは workbox.backgroundSync.* にあります。

例として、Workbox モジュールを参照する import ステートメントを使用するコードを次に示します。

import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {CacheableResponse} from 'workbox-cacheable-response';

registerRoute(
  ({request}) => request.destination === 'image',
  new CacheFirst({
    plugins: [new CacheableResponsePlugin({statuses: [0, 200]})],
  })
);

workbox-sw を使用するように書き換えたコードは次のようになります(import ステートメントのみが変更されており、ロジックは変更されていません)。

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

const {registerRoute} = workbox.routing;
const {CacheFirst} = workbox.strategies;
const {CacheableResponse} = workbox.cacheableResponse;

registerRoute(
  ({request}) => request.destination === 'image',
  new CacheFirst({
    plugins: [new CacheableResponsePlugin({statuses: [0, 200]})],
  })
);