このガイドでは、Workbox v6 で導入された互換性のない変更に焦点を当て、Workbox v5 からアップグレードする際に必要な変更の例を示します。
互換性に対応しない変更
workbox-core
workbox-core
の skipWaiting()
メソッドは 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() に渡された同様のオプションに代わる)の各プロパティをサポートしています。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
オプションはサポート対象外であり、削除されました。これは、InjectManifest
プラグインで mode
をサポートしている workbox-webpack-plugin
には適用されません。
ビルドツールに 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()
が追加されました。これにより、「待機中」のサービス ワーカーに有効化を通知するプロセスが簡素化されます。これにより、次のような改善がもたらされます。
- デファクト スタンダード メッセージ本文
{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-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
戦略でナビゲーション リクエストのレスポンスを生成できない場合(つまり、カスタム オフライン 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 で問題を報告してください。