このガイドでは、Workbox v6 で導入された互換性を破る変更に焦点を当て、Workbox v5 からアップグレードする際に必要な変更の例を示します。
互換性を破る変更
workbox-core
workbox-core の skipWaiting() メソッドは install ハンドラを追加しなくなり、self.skipWaiting() を呼び出すだけになります。
skipWaiting() は Workbox v7 で削除される可能性が高いため、今後は self.skipWaiting() を使用してください。
workbox-precaching
- HTTP リダイレクトに対応する URL のクロスオリジン HTML ドキュメントは、
workbox-precachingを使用したナビゲーション リクエストを満たすために使用できなくなりました。このシナリオは一般的にはまれです。 fbclidURL クエリ パラメータは、特定のリクエストの事前キャッシュされたレスポンスを検索するときにworkbox-precachingによって無視されるようになりました。PrecacheControllerコンストラクタは、文字列ではなく、特定のプロパティを持つオブジェクトをパラメータとして受け取るようになりました。このオブジェクトは、cacheName(v5 でコンストラクタに渡された文字列と同じ目的を果たす)、plugins(v5 のaddPlugins()メソッドを置き換える)、fallbackToNetwork(v5 でcreateHandler()と `createHandlerBoundToURL() に渡された同様のオプションを置き換える)のプロパティをサポートしています。PrecacheControllerのinstall()メソッドと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-routingのRouterクラスを使用する「実際の」ルートになりました。registerRoute()とprecacheAndRoute()の呼び出しをインターリーブすると、ルートの評価順序が異なる場合があります。
workbox-routing
setDefaultHandler() メソッドは、適用される HTTP メソッドに対応するオプションの 2 番目のパラメータを受け取るようになりました。デフォルトは 'GET' です。
setDefaultHandler()を使用していて、すべてのリクエストがGETの場合は、変更する必要はありません。GET以外のリクエスト(POST、PUTなど)がある場合は、setDefaultHandler()が原因でこれらのリクエストが一致することはなくなります。
ビルド構成
workbox-build と workbox-cli の getManifest モードと injectManifest モードの mode オプションは、サポートを意図したものではなかったため、削除されました。これは workbox-webpack-plugin には適用されません。 は、InjectManifest プラグインで mode をサポートしています。
ビルドツールには Node.js v10 以降が必要
v10 より前の Node.js バージョンは、workbox-webpack-plugin、workbox-build、workbox-cli でサポートされなくなりました。v8 より前のバージョンの Node.js を実行している場合は、ランタイムをサポートされているバージョンに更新します。
新しい改善点
workbox-strategies
Workbox v6 では、サードパーティのデベロッパーが独自の Workbox 戦略を定義するための新しい方法が導入されています。これにより、サードパーティのデベロッパーは、ニーズを完全に満たす方法で Workbox を拡張できます。
新しい Strategy 基本クラス
v6 では、すべての Workbox 戦略クラスが新しい Strategy 基本クラスを拡張する必要があります。これをサポートするために、すべての組み込み戦略が書き換えられました。
Strategy 基本クラスは、主に次の 2 つのことを行います。
- すべての戦略ハンドラに共通するプラグイン ライフサイクル コールバックを呼び出す(開始、応答、終了時など)。
- 「ハンドラ」インスタンスを作成する。これは、戦略が処理している個々のリクエストの状態を管理できます。
新しい「ハンドラ」クラス
以前は、内部モジュールが fetchWrapper と cacheWrapper を呼び出していました。これらは(名前が示すように)さまざまなフェッチ 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() が追加され、「待機中」の Service Worker を有効にするプロセスが簡素化されました。これにより、次のような改善が実現します。
- この関数は、Workbox によって生成された Service Worker が
skipWaiting()をトリガーするためにチェックする、デファクト スタンダードのメッセージ本文{type: 'SKIP_WAITING'}を使用してpostMessage()を呼び出します。 workbox-windowが登録されたサービス ワーカーとは異なる場合でも、このメッセージを送信する正しい「待機中」のサービス ワーカーを選択します。
isExternal プロパティを優先して「外部」イベントを削除
workbox-window のすべての「外部」イベントが削除され、isExternal プロパティが true に設定された「通常」イベントに置き換えられました。これにより、この区別を重視するデベロッパーは引き続き区別を検出でき、知る必要のないデベロッパーはプロパティを無視できます。
「ユーザーにページのリロードを提案する」レシピを簡素化
上記の 2 つの変更により、「ユーザーにページのリロードを提案する」レシピを簡素化できます。
// 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-expiration で matchOptions を設定できるようになりました。これは、CacheQueryOptions として基盤となる cache.delete() 呼び出しに渡されます。(ほとんどのデベロッパーは、この操作を行う必要はありません)。
workbox-precaching
workbox-strategies を使用する
workbox-precaching は、workbox-strategies をベースとして使用するように書き換えられました。これにより、互換性を破る変更が発生することはなく、2 つのモジュールがネットワークとキャッシュにアクセスする方法の長期的な整合性が向上します。
プリキャッシュでエントリが一括ではなく 1 つずつ処理されるようになりました
workbox-precaching が更新され、プリキャッシュ マニフェスト内のエントリが一度に 1 つだけリクエストされ、キャッシュに保存されるようになりました。これまでは、すべてのエントリを一度にリクエストしてキャッシュに保存しようとしていました(スロットリングの方法はブラウザに任されていました)。
これにより、プリキャッシュ中の net::ERR_INSUFFICIENT_RESOURCES エラーの可能性が低減され、プリキャッシュとウェブアプリによる同時リクエスト間の帯域幅の競合も軽減されます。
PrecacheFallbackPlugin を使用すると、オフライン フォールバックが容易になる
workbox-precaching に PrecacheFallbackPlugin が追加されました。これは、v6 で追加された新しい handlerDidError ライフサイクル メソッドを実装します。
これにより、レスポンスが利用できない場合に、特定の戦略の「代替」として事前キャッシュされた URL を簡単に指定できます。このプラグインは、必要なリビジョン パラメータなど、事前キャッシュされた URL の正しいキャッシュキーを適切に作成します。
次の例では、NetworkOnly 戦略でナビゲーション リクエストのレスポンスを生成できない場合に、プリキャッシュされた /offline.html でレスポンスを返すために使用しています。つまり、カスタムのオフライン 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 で問題を報告してください。