Workbox v2 から v3 に移行する

このガイドでは、Workbox v3 で導入された互換性を破る変更に重点を置き、Workbox v2 の設定からアップグレードする際に必要となる変更の例を紹介します。

従来の sw-precachesw-toolbox の組み合わせを使用していて、初めて Workbox に移行する場合は、こちらの別の移行ガイドをご覧ください。

v3 の背景

Workbox の v3 リリースでは、既存のコードベースの重要なリファクタリングが行われます。包括的な目標は次のとおりです。

  • ワークボックスのサイズを最小化します。ダウンロードおよび実行される Service Worker ランタイム コードの量が削減されました。モノリシック バンドルにすべてのユーザーをオプトインするのではなく、使用している特定の機能のコードのみが実行時にインポートされます。
  • Workbox に CDN がある。Workbox ランタイム ライブラリにアクセスするための正規オプションとして、完全にサポートされている Google Cloud Storage ベースの CDN ホスティングを提供しています。これにより、Workbox を簡単に稼働できるようになります。
  • デバッグとログの改善。デバッグとロギングのエクスペリエンスが大幅に改善されました。localhost オリジンから Workbox が使用され、すべてのロギングとアサーションが本番環境ビルドから削除されるたびに、デバッグログがデフォルトで有効になります。 Workbox v3 が提供するデバッグ ロギングの例。
  • Webpack プラグインの改善。workbox-webpack-plugin は webpack ビルドプロセスとより緊密に統合されているため、ビルド パイプライン内のすべてのアセットを事前キャッシュする必要がある場合、構成不要のユースケースが可能です。

これらの目標を達成し、以前のインターフェースの気まずさに感じた、またはアンチパターンにつながる部分をクリーンアップするには、v3 リリースで多くの破壊的変更を導入する必要がありました。

互換性に対応しない変更

ビルド構成

以下の変更は、共通の構成オプション セットを共有するすべてのビルドツール(workbox-buildworkbox-cliworkbox-webpack-plugin)の動作に影響します。

  • 'fastest' ハンドラ名は以前は有効で、runtimeCaching の構成時に 'staleWhileRevalidate' のエイリアスとして扱われていました。現在は無効になっているため、デベロッパーは 'staleWhileRevalidate' を直接使用するように切り替える必要があります。
  • いくつかの runtimeCaching.options プロパティ名が更新され、無効な構成が使用されている場合にビルドが失敗する原因となる追加のパラメータ検証が導入されました。現在サポートされているオプションの一覧については、runtimeCachingドキュメントをご覧ください。

workbox-background-sync

  • maxRetentionTime 構成パラメータが、ミリ秒ではなく分数として解釈されるようになりました。
  • そこで、キュー名を表す必須の文字列を追加しました。この文字列は、Plugin クラスまたはスタンドアロン クラスを作成する際、最初のパラメータとして渡す必要があります。(以前はオプションのプロパティとして渡されていました)。更新された API サーフェスについては、ドキュメントをご覧ください。

workbox-broadcast-cache-update

  • そこで、チャンネル名を表す必須の文字列を追加しました。この文字列は、Plugin クラスまたはスタンドアロン クラスを作成する際、最初のパラメータとして渡す必要があります。

たとえば、v2 では、Plugin クラスを次のように初期化します。

new workbox.broadcastCacheUpdate.BroadcastCacheUpdatePlugin({
  channelName: 'cache-updates',
  headersToCheck: ['etag'],
});

v3 での同等の使用法は次のとおりです。

new workbox.broadcastUpdate.Plugin('cache-updates', {headersToCheck: ['etag']});

更新された API サーフェスについては、ドキュメントをご覧ください。

workbox-build

  • デフォルトでは、glob パターン マッチングは オプション follow: true(シンボリック リンクに続く)と strict: true(異常なエラーに対する耐性が低くなります)で実行されるようになりました。ビルド構成で globFollow: falseglobStrict: false を設定すると、どちらも無効にして以前の動作に戻すことができます。
  • workbox-build の関数はすべて、返されるレスポンスで追加のプロパティ warnings を返します。v2 では致命的なエラーとして扱われていた一部のシナリオが許可され、文字列の配列である warnings でレポートされるようになりました。

v2 では、次のように generateSW を呼び出すことができます。

const workboxBuild = require('workbox-build');

workboxBuild.generateSW({...})
  .then(({count, size}) => console.log(`Precached ${count} files, totaling ${size} bytes.`))
  .catch((error) => console.error(`Something went wrong: ${error}`));

v3 でも同じコードを使用できますが、warnings がないか確認してログに記録することをおすすめします。

const workboxBuild = require('workbox-build');

workboxBuild.generateSW({...})
  .then(({count, size, warnings}) => {
    for (const warning of warnings) {
      console.warn(warning);
    }
    console.log(`Precached ${count} files, totalling ${size} bytes.`);
  })
  .catch((error) => console.error(`Something went wrong: ${error}`));
  • v2 で独自のカスタム ManifestTransform 関数を記述したデベロッパーは、オブジェクト内でマニフェスト配列を返す必要があります(つまり、return manifestArray; の代わりに return {manifest: manifestArray}; を使用する必要があります)。これにより、プラグインにオプションの warnings プロパティを含めることができます。このプロパティは、致命的でない警告情報を含む文字列の配列になります。

v2 でカスタム ManifestTransform を作成する場合は、次のようなコードを使用します。

const cdnTransform = manifestEntries => {
  return manifestEntries.map(entry => {
    const cdnOrigin = 'https://example.com';
    if (entry.url.startsWith('/assets/')) {
      entry.url = cdnOrigin + entry.url;
    }
    return entry;
  });
};

次の v3 と同等です。

const cdnTransform = manifestEntries => {
  const manifest = manifestEntries.map(entry => {
    const cdnOrigin = 'https://example.com';
    if (entry.url.startsWith('/assets/')) {
      entry.url = cdnOrigin + entry.url;
    }
    return entry;
  });
  return {manifest, warnings: []};
};
  • getFileManifestEntries() 関数の名前が getManifest() に変更されました。返される Promise には、プレキャッシュされた URL に関する追加情報が含まれるようになりました。

v2 では、次のようなコードを使用します。

const manifestEntries = await workboxBuild.getFileManifestEntries({...});

v3 では、次のように書き換えることができます。

const {manifestEntries, count, size, warnings} = await workboxBuild.getManifest({...});

// Use manifestEntries like before.
// Optionally, log the new info returned in count, size, warnings.
  • generateFileManifest() 関数は削除されました。代わりに getManifest() を呼び出し、そのレスポンスを使用して適切な形式でデータをディスクに書き込むことをおすすめします。

workbox-cache-expiration

  • プラグイン API はこれまでと変わりません。ほとんどのデベロッパーが最終的に使用するモードです。ただし、この API をスタンドアロン クラスとして使用するデベロッパーに影響する重要な変更があります。更新された API サーフェスについては、ドキュメントをご覧ください。

workbox-cli

デベロッパーは、--help フラグを指定して CLI を実行し、サポートされているすべてのパラメータのセットを指定できます。

  • バイナリ スクリプトの workbox-cli エイリアスのサポートは終了しました。これで、バイナリには workbox としてのみアクセスできるようになりました。
  • v2 のコマンド generate:swinject:manifest の名前が、v3 で generateSWinjectManifest に変更されました。
  • v2 では、(明示的に指定されていない場合に使用)デフォルトの構成ファイルは、現在のディレクトリにある workbox-cli-config.js であると想定されていました。v3 では workbox-config.js です。

まとめると、v2 では次のようなことが起こります。

$ workbox inject:manifest

「マニフェストの挿入」を実行して、ビルドプロセスで、workbox-cli-config.js から読み取った構成を使用します。v3 の場合は、次のようになります。

$ workbox injectManifest

同様のことを行いますが、workbox-config.js から構成を読み取ります。

ワークボックスプレキャッシュ

  • 以前の precache() メソッドは、キャッシュの変更と、キャッシュに保存されたエントリを提供するルーティングの設定の両方を行いました。現在、precache() はキャッシュ エントリを変更するだけであり、キャッシュされたレスポンスを提供するルートを登録するための新しいメソッド addRoute() が公開されています。以前の 2-in-1 機能が必要な場合は、precacheAndRoute() の呼び出しに切り替えることができます。
  • 以前は WorkboxSW コンストラクタを介して構成されていたいくつかのオプションが、workbox.precaching.precacheAndRoute([...], options)options パラメータとして渡されるようになりました。これらのオプションのデフォルトが構成されていない場合は、リファレンス ドキュメントに記載されています。
  • デフォルトでは、ファイル拡張子のない URL は、自動的に .html 拡張子を含むキャッシュ エントリとの一致がチェックされます。たとえば、(プリキャッシュされていない)/path/to/index に対するリクエストが行われ、/path/to/index.html のプリキャッシュ エントリがある場合、そのプリキャッシュ エントリが使用されます。デベロッパーは、workbox.precaching.precacheAndRoute() にオプションを渡すときに {cleanUrls: false} を設定することで、この新しい動作を無効にできます。
  • 事前キャッシュ済みアセットのキャッシュの更新を通知するように、workbox-broadcast-update が自動的に設定されなくなります。

v2 の次のコード:

const workboxSW = new self.WorkboxSW({
  directoryIndex: 'index.html',
  ignoreUrlParametersMatching: [/^utm_/],
  precacheChannelName: 'precache-updates',
});
workboxSW.precache([...]);

次の v3 と同等です。

workbox.precaching.addPlugins([
    new workbox.broadcastUpdate.Plugin('precache-updates')
]);

workbox.precaching.precacheAndRoute([...], {
  cleanUrls: false,
  directoryIndex: 'index.html',
  ignoreUrlParametersMatching: [/^utm_/],
});

ワークボックス ルーティング

  • 以前に WorkboxSW オブジェクトの workbox.router.* 名前空間を介して workbox-routing を使用していたデベロッパーは、新しい名前空間 workbox.routing.* に切り替える必要があります。
  • ルートは、登録された優先順に評価されるようになりました。これは、v2 で使用されていた Route の評価とはの順序であり、最後に登録された Route が優先されるものです。
  • ExpressRoute クラスと、「Express-style」のサポートワイルドカードは削除されました。これにより、workbox-routing のサイズが大幅に小さくなります。workbox.routing.registerRoute() の最初のパラメータとして使用される文字列は、完全一致として扱われます。ワイルドカードや部分一致は RegExp で処理されます。リクエスト URL の一部またはすべてと一致する RegExp を使用すると、ルートがトリガーされます。
  • Router クラスの addFetchListener() ヘルパー メソッドが削除されました。デベロッパーは、独自の fetch ハンドラを明示的に追加することも、fetch ハンドラを暗黙的に作成する workbox.routing が提供するインターフェースを使用することもできます。
  • registerRoutes() メソッドと unregisterRoutes() メソッドが削除されました。単一の Route で動作するメソッドのバージョンは変更されていません。複数のルートの登録または登録解除を同時に行う必要があるデベロッパーは、代わりに registerRoute() または unregisterRoute() を一連の呼び出しを行う必要があります。

v2 の次のコード:

const workboxSW = new self.WorkboxSW();

workboxSW.router.registerRoute(
  '/path/with/.*/wildcard/',
  workboxSW.strategies.staleWhileRevalidate()
);

workboxSW.router.registerRoute(
  new RegExp('^https://example.com/'),
  workboxSW.strategies.networkFirst()
);

次の v3 と同等です。

workbox.routing.registerRoute(
  new RegExp('^https://example.com/'),
  workbox.strategies.networkFirst()
);

workbox.routing.registerRoute(
  new RegExp('^/path/with/.*/wildcard'),
  workbox.strategies.staleWhileRevalidate()
);

Workbox-strategies(旧称 workbox-runtime-caching)

  • workbox-runtime-caching モジュールが workbox-strategies として正式に発表され、新しい名前で npm に公開されました。
  • キャッシュ名を指定せずに戦略でキャッシュの有効期限を使用すると、無効になります。v2 では、これは可能でした。
workboxSW.strategies.staleWhileRevalidate({
  cacheExpiration: {maxEntries: 50},
});

その結果、デフォルト キャッシュのエントリが期限切れになりますが、これは予想外です。v3 では、キャッシュ名は は必須です。

workboxSW.strategies.staleWhileRevalidate({
  cacheName: 'my-cache',
  plugins: [new workbox.expiration.Plugin({maxEntries: 50})],
});
  • cacheWillMatch ライフサイクル メソッドの名前が cachedResponseWillBeUsed に変更されました。cacheWillMatch に反応する独自のプラグインをデベロッパーが作成していない限り、これはデベロッパーにとって目に見える変更ではありません。
  • 戦略の構成時にプラグインを指定する構文が変更されました。各プラグインは、戦略の構成の plugins プロパティで明示的に指定する必要があります。

v2 の次のコード:

const workboxSW = new self.WorkboxSW();

const networkFirstStrategy = workboxSW.strategies.networkFirst({
  cacheName: 'my-cache',
  networkTimeoutSeconds: 5,
  cacheExpiration: {
    maxEntries: 50,
  },
  cacheableResponse: {
    statuses: [0, 200],
  },
});

次の v3 と同等です。

const networkFirstStrategy = workbox.strategies.networkFirst({
  cacheName: 'my-cache',
  networkTimeoutSeconds: 5,
  plugins: [
    new workbox.expiration.Plugin({maxEntries: 50}),
    new workbox.cacheableResponse.Plugin({statuses: [0, 200]}),
  ],
});

詳しくは、プラグインを使用するご覧ください

ワークボックス SW

  • 内部で、workbox-sw が書き換えられて軽量の「ローダ」になりました。このインターフェースは、いくつかの基本構成を受け取り、実行時に必要となる他のモジュールを取り込む役割を担います。デベロッパーは、WorkboxSW クラスの新しいインスタンスを構築するのではなく、グローバル名前空間で自動的に公開される既存のインスタンスを操作します。

v2 の従来版:

importScripts('<path to workbox-sw>/importScripts/workbox-sw.prod.v2.1.3.js');

const workbox = new WorkboxSW({
  skipWaiting: true,
  clientsClaim: true,
  // etc.
});

workbox.router.registerRoute(...);

v3 では、workbox-sw.js スクリプトをインポートするだけで、すぐに使用できるインスタンスがグローバル名前空間で workbox として自動的に使用可能になります。

importScripts('<path to workbox-sw>/3.0.0/workbox-sw.js');

// workbox is implicitly created and ready for use.
workbox.routing.registerRoute(...);
  • skipWaitingclientsClaim は、WorkboxSW コンストラクタに渡されるオプションではなくなりました。代わりに、メソッド workbox.clientsClaim()workbox.skipWaiting() に変更されました。
  • これまで v2 コンストラクタでサポートされていた handleFetch オプションは、v3 ではサポートされなくなりました。フェッチ ハンドラを呼び出さずに Service Worker をテストするための同様の機能を必要とするデベロッパーは、[Bypass for network] を使用できます。オプションを使用します
Chrome DevTools の [Bypass for Network] オプション。

workbox-webpack-plugin

プラグインは大幅に書き換えられており、多くの場合、ゼロ構成で使用できるモードです。更新された API サーフェスについては、ドキュメントをご覧ください。

  • API は GenerateSWInjectManifest の 2 つのクラスを公開するようになりました。これにより、swSrc の存在に基づいて動作が変更された v2 の動作とは異なり、モードの切り替えが明示的に行われます。
  • デフォルトでは、webpack コンパイル パイプラインのアセットは事前キャッシュされるため、globPatterns を構成する必要はありません。globPatterns を引き続き使用する唯一の理由は、webpack ビルドに含まれていないアセットを事前キャッシュに保存する必要がある場合です。一般に、v3 プラグインに移行する場合は、まず以前の glob ベースの設定をすべて削除し、特に必要な場合にのみ再度追加する必要があります。

困ったときは

ほとんどの移行は単純明快であると予想されます。このガイドに記載されていない問題が発生した場合は、GitHub で問題を報告してお知らせください。