Workbox v5 から v6 に移行する

このガイドでは、Workbox v6 で導入された互換性のない変更に焦点を当て、Workbox v5 からアップグレードする際に必要な変更の例を示します。

互換性に対応しない変更

workbox-core

workbox-coreskipWaiting() メソッドは install ハンドラを追加しなくなり、self.skipWaiting() を呼び出すだけになります。

skipWaiting() は Workbox v7 で削除される予定であるため、今後は代わりに self.skipWaiting() を使用してください。

workbox-precaching

  • HTTP リダイレクトに対応する URL のクロスオリジン HTML ドキュメントは、workbox-precaching でナビゲーション リクエストを満たすために使用できなくなりました。通常、このシナリオは発生しません。
  • 特定のリクエストのプリキャッシュ レスポンスを検索するときに、fbclid URL クエリ パラメータが workbox-precaching によって無視されるようになりました。
  • PrecacheController コンストラクタは、文字列ではなく、特定のプロパティを持つオブジェクトをパラメータとして受け取るようになりました。このオブジェクトは、cacheName(v5 のコンストラクタに渡された文字列と同じ目的)、plugins(v5 の addPlugins() メソッドに代わる)、fallbackToNetwork(v5 の createHandler() と createHandlerBoundToURL() に渡された同様のオプションに代わる)の各プロパティをサポートしています。
  • PrecacheControllerinstall() メソッドと activate() メソッドが、それぞれ対応する InstallEvent または ActivateEvent に設定する 1 つのパラメータを受け取るようになりました。
  • addRoute() メソッドが PrecacheController から削除されました。代わりに、新しい PrecacheRoute クラスを使用してルートを作成し、登録できます。
  • precacheAndRoute() メソッドが PrecacheController から削除されました。(workbox-precaching モジュールによってエクスポートされる静的ヘルパー メソッドとして引き続き存在します)。代わりに PrecacheRoute を使用できるため削除されました。
  • createMatchCalback() メソッドが PrecacheController から削除されました。代わりに新しい PrecacheRoute を使用できます。
  • createHandler() メソッドが PrecacheController から削除されました。代わりに、PrecacheController オブジェクトの strategy プロパティを使用してリクエストを処理できます。
  • createHandler() 静的エクスポートは、workbox-precaching モジュールからすでに削除されています。代わりに、デベロッパーは PrecacheController インスタンスを作成し、その strategy プロパティを使用する必要があります。
  • precacheAndRoute() に登録されたルートは、内部で workbox-routingRouter クラスを使用する「実際の」ルートになりました。registerRoute()precacheAndRoute() の呼び出しを交互に行うと、ルートの評価順序が異なる場合があります。

workbox-routing

setDefaultHandler() メソッドは、適用される HTTP メソッドに対応するオプションの 2 番目のパラメータを受け取り、デフォルトは 'GET' になります。

  • setDefaultHandler() を使用していて、すべてのリクエストが GET である場合は、変更する必要はありません。
  • GET 以外のリクエスト(POSTPUT など)がある場合は、setDefaultHandler() によってこれらのリクエストが一致しないようにしました。

ビルド構成

workbox-buildworkbox-cligetManifest モードと injectManifest モードの mode オプションはサポート対象外であり、削除されました。これは、InjectManifest プラグインで mode をサポートしている workbox-webpack-plugin には適用されません。

ビルドツールに Node.js v10 以降が必要

v10 より前の Node.js バージョンは、workbox-webpack-pluginworkbox-buildworkbox-cli でサポートされなくなりました。v8 より前のバージョンの Node.js を実行している場合は、ランタイムをサポートされているバージョンに更新します。

新機能の改善

workbox-strategies

Workbox v6 では、サードパーティ デベロッパーが独自の Workbox 戦略を定義するための新しい方法が導入されています。これにより、サードパーティのデベロッパーは、ニーズを完全に満たす方法で Workbox を拡張できます。

新しい Strategy ベースクラス

v6 では、すべての Workbox 戦略クラスが新しい Strategy ベースクラスを拡張する必要があります。組み込みの戦略はすべて、これをサポートするように書き換えられています。

Strategy 基本クラスは、主に次の 2 つの処理を行います。

  • すべての戦略ハンドラに共通するプラグインのライフサイクル コールバックを呼び出す(開始時、応答時、終了時など)。
  • 戦略が処理する個々のリクエストの状態を管理できる「ハンドラ」インスタンスを作成します。

新しい「ハンドラ」クラス

以前は、fetchWrappercacheWrapper という内部モジュールがありました。これは、名前が示すように、さまざまな取得 API とキャッシュ API をライフサイクルにフックしてラップします。これは現在、プラグインを機能させるメカニズムですが、デベロッパーには公開されていません。

新しい「ハンドラ」クラス StrategyHandler は、これらのメソッドを公開するため、カスタム戦略で fetch() または cacheMatch() を呼び出し、戦略インスタンスに追加されたプラグインを自動的に呼び出すことができます。

このクラスにより、デベロッパーは独自のカスタム ライフサイクル コールバックを追加して、戦略に固有のコールバックを追加できます。これらのコールバックは、既存のプラグイン インターフェースで「そのまま機能」します。

新しいプラグインのライフサイクルの状態

Workbox v5 では、プラグインはステートレスです。つまり、/index.html のリクエストが requestWillFetch コールバックと cachedResponseWillBeUsed コールバックの両方をトリガーした場合、これらの 2 つのコールバックは相互に通信する方法がなく、同じリクエストによってトリガーされたことを認識することさえできません。

v6 では、すべてのプラグイン コールバックに新しい state オブジェクトも渡されます。この状態オブジェクトは、この特定のプラグイン オブジェクトとこの特定の戦略呼び出し(handle() の呼び出し)に固有のものです。これにより、デベロッパーは、1 つのコールバックが同じプラグイン内の別のコールバックの動作に基づいて条件付きで何かを行うことができるプラグインを作成できます(例: requestWillFetch の実行と fetchDidSucceed または fetchDidFail の実行の間の時間差を計算する)。

新しいプラグインのライフサイクル コールバック

新しいプラグイン ライフサイクル コールバックが追加され、デベロッパーはプラグインのライフサイクル ステータスを最大限に活用できるようになりました。

  • handlerWillStart: ハンドラ ロジックの実行が開始される前に呼び出されます。このコールバックを使用して、初期ハンドラの状態を設定できます(開始時間を記録するなど)。
  • handlerWillRespond: 戦略の handle() メソッドがレスポンスを返す前に呼び出されます。このコールバックを使用すると、ルート ハンドラやその他のカスタム ロジックにレスポンスを返す前に、そのレスポンスを変更できます。
  • handlerDidRespond: 戦略の handle() メソッドがレスポンスを返した後に呼び出されます。このコールバックは、他のプラグインによる変更後など、最終的なレスポンスの詳細を記録するために使用できます。
  • handlerDidComplete: この戦略の呼び出しからイベントに追加されたすべての存続期間延長プロミスが決済された後に呼び出されます。このコールバックは、計算するためにハンドラが完了するまで待機する必要があるデータ(キャッシュ ヒット ステータス、キャッシュ レイテンシ、ネットワーク レイテンシなど)を報告するために使用できます。
  • handlerDidError: ハンドラがどのソースからも有効なレスポンスを提供できなかった場合に呼び出されます。このコールバックは、ネットワーク エラーの代わりに「フォールバック」コンテンツを提供するために使用できます。

独自のカスタム戦略を実装するデベロッパーは、これらのコールバックを自分で呼び出す必要はありません。すべて新しい Strategy ベースクラスによって処理されます。

ハンドラのより正確な TypeScript 型

さまざまなコールバック メソッドの TypeScript 定義が正規化されました。これにより、TypeScript を使用して独自のコードを記述し、ハンドラを実装または呼び出すデベロッパーの利便性が向上します。

workbox-window

新しい messageSkipWaiting() メソッド

workbox-window モジュールに新しいメソッド messageSkipWaiting() が追加されました。これにより、「待機中」のサービス ワーカーに有効化を通知するプロセスが簡素化されます。これにより、次のような改善がもたらされます。

  • デファクト スタンダード メッセージ本文 {type: 'SKIP_WAITING'} を指定して postMessage() を呼び出します。Workbox によって生成されたサービス ワーカーは、skipWaiting() をトリガーするためにこの本文をチェックします。
  • workbox-window が登録されている Service Worker とは異なる場合でも、このメッセージを送信する正しい「待機中」の Service Worker が選択されます。

isExternal プロパティに置き換えて「外部」イベントを削除

workbox-window のすべての「外部」イベントが削除され、代わりに isExternal プロパティが true に設定された「通常」のイベントが追加されました。これにより、区別を重視するデベロッパーは引き続き区別を検出でき、区別を把握する必要がないデベロッパーはプロパティを無視できます。

クリーンアップ リクエスト「ユーザーにページの再読み込みを提案」

上記の両方の変更により、「ユーザーにページの再読み込みを提示する」レシピを簡素化できます。

// v6:
<script type="module">
  import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.0.0-alpha.1/workbox-window.prod.mjs';

  if ('serviceWorker' in navigator) {
    const wb = new Workbox('/sw.js');

    const showSkipWaitingPrompt = () => {
      // This assumes a hypothetical createUIPrompt() method with
      // onAccept and onReject callbacks:
      const prompt = createUIPrompt({
        onAccept: () => {
          wb.addEventListener('controlling', () => {
            window.location.reload();
          });

          // This will postMessage() to the waiting service worker.
          wb.messageSkipWaiting();
        },

        onReject: () => {
          prompt.dismiss();
        },
      });
    };

    // Listening for externalwaiting is no longer needed.
    wb.addEventListener('waiting', showSkipWaitingPrompt);
    wb.register();
  }
</script>

workbox-routing

新しいブール値パラメータ sameOrigin が、workbox-routing で使用される matchCallback 関数に渡されます。リクエストが同一オリジンの URL の場合は true に設定され、それ以外の場合は false に設定されます。

これにより、一般的なボイラープレートが簡素化されます。

// In v5:
registerRoute(
  ({url}) =>
    url.origin === self.location.origin && url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'})
);

// In v6:
registerRoute(
  ({sameOrigin, url}) => sameOrigin && url.pathname.endsWith('.png'),
  new StaleWhileRevalidate({cacheName: 'local-png'})
);

workbox-expiration の matchOptions

workbox-expirationmatchOptions を設定できるようになりました。この値は、CacheQueryOptions として基盤となる cache.delete() 呼び出しに渡されます。(ほとんどのデベロッパーは、この操作を行う必要はありません)。

workbox-precaching

workbox-strategies を使用している

workbox-precaching を書き換えて、workbox-strategies をベースとして使用するようにしました。これにより、破壊的な変更は発生せず、2 つのモジュールがネットワークとキャッシュにアクセスする方法の長期的な一貫性が向上します。

プリキャッシュでエントリを一括ではなく 1 つずつ処理する

workbox-precaching が更新され、プリキャッシュ マニフェスト内のエントリをすべて一度にリクエストしてキャッシュに保存しようとするのではなく、一度に 1 つのエントリのみをリクエストしてキャッシュに保存するようにしました(スロットリング方法の決定はブラウザに任せます)。

これにより、プリキャッシュ中の net::ERR_INSUFFICIENT_RESOURCES エラーの発生可能性が低下し、プリキャッシュとウェブアプリによる同時リクエスト間の帯域幅競合も軽減されます。

PrecacheFallbackPlugin によりオフライン フォールバックが容易に

workbox-precachingPrecacheFallbackPlugin が追加されました。これは、v6 で追加された新しい handlerDidError ライフサイクル メソッドを実装します。

これにより、レスポンスが利用できない場合に、特定の戦略の「フォールバック」としてプリキャッシュ済み URL を簡単に指定できます。プラグインは、必要なリビジョン パラメータなど、プリキャッシュ URL の正しいキャッシュキーを適切に構築します。

NetworkOnly 戦略でナビゲーション リクエストのレスポンスを生成できない場合(つまり、カスタム オフライン HTML ページを表示する場合)に、プリキャッシュされた /offline.html でレスポンスを返す例を次に示します。

import {PrecacheFallbackPlugin, precacheAndRoute} from 'workbox-precaching';
import {registerRoute} from 'workbox-routing';
import {NetworkOnly} from 'workbox-strategies';

// Ensure that /offline.html is part of your precache manifest!
precacheAndRoute(self.__WB_MANIFEST);

registerRoute(
  ({request}) => request.mode === 'navigate',
  new NetworkOnly({
    plugins: [
      new PrecacheFallbackPlugin({
        fallbackURL: '/offline.html',
      }),
    ],
  })
);

ランタイム キャッシュの precacheFallback

サービス ワーカーを手動で記述するのではなく、generateSW を使用してサービス ワーカーを作成する場合は、runtimeCaching の新しい precacheFallback 構成オプションを使用して同じことを実現できます。

{
  // ... other generateSW config options...
  runtimeCaching: [{
    urlPattern: ({request}) => request.mode === 'navigate',
    handler: 'NetworkOnly',
    options: {
      precacheFallback: {
        // This URL needs to be included in your precache manifest.
        fallbackURL: '/offline.html',
      },
    },
  }],
}

ヘルプ

ほとんどの移行は簡単な作業になる見込みです。このガイドに記載されていない問題が発生した場合は、GitHub で問題を報告してください。