このガイドでは、Workbox v5 で導入された互換性を破る変更に重点を置き、Workbox v4 からアップグレードする際に必要となる変更の例を紹介します。
互換性に対応しない変更
プラグイン クラス名の変更
多くの Workbox v4 パッケージには、Plugin
という名前のクラスが含まれていました。v5 では、これらのクラスの名前が、パッケージ ID + Plugin
というパターンに従って変更されました。
BackgroundSyncPlugin
BroadcastUpdatePlugin
CacheableResponsePlugin
ExpirationPlugin
RangeRequestsPlugin
この名前変更は、モジュール インポートと workbox.*
名前空間のどちらでクラスを使用しているかにかかわらず適用されます。
デフォルトのプリキャッシュ マニフェストの置換ポイント
以前は、「マニフェストの挿入」でビルドツールのいずれかを使用した場合、モードでは、ソースの Service Worker ファイルに precacheAndRoute([])
が存在するかどうかが確認されます。この空の配列 []
が、プリキャッシュ マニフェストが挿入されたポイントのプレースホルダとして使用されました。
Workbox v5 では、置換ロジックが変更され、デフォルトで self.__WB_MANIFEST
が挿入ポイントとして使用されるようになりました。
// v4:
precacheAndRoute([]);
// v5:
precacheAndRoute(self.__WB_MANIFEST);
こちらのディスカッションで説明されているように、この変更により、エクスペリエンスが簡素化されるとともに、デベロッパーはカスタム サービス ワーカー コード内で挿入されたマニフェストの使用方法をより細かく制御できるようになります。必要に応じて、この置換文字列は injectionPoint
構成オプションで変更できます。
ナビゲーション ルートの変更
ナビゲーション ルートで以前サポートされていた 2 つのオプション(blacklist
と whitelist
)の名前が denylist
と allowlist
に変更されました。
workbox-routing
は以前、registerNavigationRoute()
というメソッドをサポートしていました。このメソッドは、内部で次の 2 つの処理を行います。
- 特定の
fetch
イベントにmode
が'navigate'
であるかどうかが検出されました。 - その場合、移動先の URL に関係なく、以前にキャッシュされたハードコードされた URL のコンテンツを使用して、そのリクエストに応答しました。
これは、App Shell アーキテクチャを実装するときに使用する一般的なパターンです。
2 つ目のステップ(キャッシュからの読み取りによってレスポンスを生成する)は、workbox-routing
の役割から外れています。新しいメソッド createHandlerBoundToURL()
を介して、workbox-precaching
の一部であるべき機能と見なされています。この新しいメソッドは、workbox-routing
の既存の NavigationRoute
クラスと連携して、同じロジックを実行できます。
ビルドツールのいずれかの「generate SW」モードで navigateFallback
オプションを使用している場合、切り替えは自動的に実行されます。navigateFallbackBlacklist
オプションまたは navigateFallbackWhitelist
オプションを以前に構成した場合は、それぞれ navigateFallbackDenylist
または navigateFallbackAllowlist
に変更します。
「マニフェストの挿入」モードを使用している場合や、サービス ワーカーを自分で作成している場合、Workbox v4 サービス ワーカーが registerNavigationRoute()
を直接呼び出す場合は、同等の動作を実現するためにコードを変更する必要があります。
// v4:
import {getCacheKeyForURL} from 'workbox-precaching';
import {registerNavigationRoute} from 'workbox-routing';
const appShellCacheKey = getCacheKeyForURL('/app-shell.html');
registerNavigationRoute(appShellCacheKey, {
whitelist: [...],
blacklist: [...],
});
// v5:
import {createHandlerBoundToURL} from 'workbox-precaching';
import {NavigationRoute, registerRoute} from 'workbox-routing';
const handler = createHandlerBoundToURL('/app-shell.html');
const navigationRoute = new NavigationRoute(handler, {
allowlist: [...],
denylist: [...],
});
registerRoute(navigationRoute);
getCacheKeyForURL()
を呼び出す必要はなく、createHandlerBoundToURL()
が自動的に処理します。
workbox-strategies から makeRequest() を削除
makeRequest()
を呼び出すことは、workbox-strategy
クラスのいずれかで handle()
を呼び出すこととほぼ同じです。2 つの方法の違いは非常に小さく、両方を使用する意味がありませんでした。makeRequest()
を呼び出していたデベロッパーは、追加の変更なしで handle()
の使用に切り替えることができます。
// v4:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.makeRequest({event, request});
// v5:
const strategy = new StaleWhileRevalidate({...});
const response = await strategy.handle({event, request});
v5 では、handle()
は request
を必須パラメータとして扱い、event.request
を使用するフォールバックは行いません。handle()
を呼び出すときは、有効なリクエストを渡してください。
workbox-broadcast-update で常に postMessage()
を使用
v4 では、workbox-broadcast-update
ライブラリはデフォルトで、サポートされている場合は Broadcast Channel API を使用してメッセージを送信し、Broadcast Channel がサポートされていない場合にのみ postMessage()
にフォールバックしていました。
2 つの潜在的な受信メッセージの送信元をリッスンする必要があるため、クライアントサイドのコードが過度に複雑になることがわかりました。また、一部のブラウザでは、Service Worker からクライアント ページに送信された postMessage()
呼び出しは、message
イベント リスナーが設定されるまで自動的にバッファリングされます。Broadcast Channel API にはバッファリング機能はありません。クライアント ページが受信の準備を整える前に送信されたブロードキャスト メッセージは破棄されます。
そのため、v5 では常に postMessage()
を使用するように workbox-broadcast-update
を変更しました。メッセージは、現在の Service Worker のスコープ内にあるすべてのクライアント ページに 1 つずつ送信されます。
この新しい動作に対応するには、クライアント ページで BroadcastChannel
インスタンスを作成したコードを削除し、代わりに navigator.serviceWorker
で message
イベント リスナーをセットアップします。
// v4:
const updatesChannel = new BroadcastChannel('api-updates');
updatesChannel.addEventListener('message', event => {
const {cacheName, updatedUrl} = event.data.payload;
// ... your code here ...
});
// v5:
// This listener should be added as early as possible in your page's lifespan
// to ensure that messages are properly buffered.
navigator.serviceWorker.addEventListener('message', event => {
// Optional: ensure the message came from workbox-broadcast-update
if (event.meta === 'workbox-broadcast-update') {
const {cacheName, updatedUrl} = event.data.payload;
// ... your code here ...
}
});
workbox-window
ユーザーは、内部ロジックが postMessage()
呼び出しをリッスンするように更新されているため、変更する必要はありません。
ビルドツールには Node.js v8 以降が必要
v8 より前の Node.js バージョンは、workbox-webpack-plugin
、workbox-build
、workbox-cli
でサポートされなくなりました。バージョン 8 より前の Node.js を実行している場合は、ランタイムをサポートされているバージョンに更新します。
workbox-webpack-plugin webpack v4 以降が必要
workbox-webpack-plugin
を使用している場合は、webpack v4 以降を使用するように webpack の設定を更新します。
ビルドツール オプションの刷新
多くの workbox-build
、workbox-cli
、workbox-webpack-plugin
構成パラメータはサポートされなくなりました。たとえば、generateSW
は常にローカルの Workbox ランタイム バンドルを作成するため、importWorkboxFrom
オプションは意味をなさなくなります。
サポートされているオプションの一覧については、関連するツールのドキュメントをご覧ください。
workbox-build から generateSWString を削除
generateSWString
モードは workbox-build
から削除されました。この機能は主に workbox-webpack-plugin
で内部的に使用されていたため、影響は最小限にとどまると見込まれます。
オプションの変更
モジュール インポートの使用
この変更は a)任意であり、b)Workbox v4 を使用する場合は技術的に可能ですが、v5 への移行に際して予想される最大の変更は、Workbox のモジュールをインポートして独自のバンドルされた Service Worker を作成するモデルです。このアプローチは、Service Worker の上部で importScripts('/path/to/workbox-sw.js')
を呼び出し、workbox.*
名前空間を介して Workbox を使用する代わりに使用できます。
[Generate SW] でビルドツール(workbox-webpack-plugin
、workbox-build
、workbox-cli
)のいずれかを使用している場合この変更が自動的に適用されます。これらのツールはすべて、サービス ワーカー ロジックの実装に必要な実際のコードとともに、Workbox ランタイムのローカル カスタム バンドルを出力します。このシナリオでは、workbox-sw
や Workbox の CDN コピーに依存する必要がなくなります。inlineWorkboxRuntime
構成の値に応じて、Workbox ランタイムは個別のファイルに分割され、Service Worker とともにデプロイされるか(false
に設定されている場合はデフォルト)、または Service Worker のロジックと一緒にインラインで組み込まれます(true
に設定されている場合)。
ビルドツールを「マニフェストの挿入」モードで使用している場合や、Workbox のビルドツールをまったく使用していない場合は、既存の Workbox でバンドルツール(webpack / Rollup)を使用するガイドで、独自の Workbox ランタイム バンドルの作成について詳細を確認してください。
v5 のドキュメントと例は、モジュールが構文をインポートすることを前提として作成されていますが、workbox.*
名前空間は Workbox v5 でも引き続きサポートされます。
プリキャッシュされたレスポンスを読み取る
precacheAndRoute()
メソッドを介して暗黙的に使用せずに、プリキャッシュされたレスポンスをキャッシュから直接読み取る必要があるデベロッパーもいます。v4 の一般的なパターンは、まず事前キャッシュ済みリソースの現在のバージョンに固有のキャッシュキーを取得し、そのキーをプリキャッシュのキャッシュ名とともに caches.match()
に渡して Response
を取得するというものです。
このプロセスを簡素化するために、v5 の workbox-precaching
では、同等の新しいメソッド matchPrecache()
がサポートされています。
// v4:
import {cacheNames} from 'workbox-core';
import {getCacheKeyForURL} from 'workbox-precaching';
const cachedResponse = await caches.match(
getCacheKeyForURL(`/somethingPrecached`),
{
cacheName: cacheNames.precache,
}
);
// v5:
import {matchPrecache} from 'workbox-precaching';
const cachedResponse = await matchPrecache(`/somethingPrecached`);
TypeScript の導入
v5 では、Workbox ランタイム ライブラリは TypeScript で記述されています。Google は、TypeScript を導入していないデベロッパーに対応するために、トランスパイルされた JavaScript モジュールとバンドルを引き続き公開しますが、TypeScript を使用している場合は、Workbox プロジェクトから直接、常に最新の型情報を利用できます。
移行の例
このコミット 非常に複雑な移行をインラインの解説付きで示しています。ロールアップを使用して ランタイムを CDN から読み込むのではなく、最終的な Service Worker でカスタム Workbox ランタイムを使用します。
すべての破壊的変更を網羅しているわけではありませんが、1 つの Service Worker ファイルを v4 から v5 にアップグレードした際の前と後を、TypeScript への切り替えを含めて示します。
ヘルプ
ほとんどの移行は単純明快であると予想されます。このガイドに記載されていない問題が発生した場合は、GitHub で問題を報告してください。