本指南著重於 Workbox 6 版中導入的破壞性變更,並舉例說明從 Workbox 5 版升級時需要進行哪些變更。
破壞性變更
workbox-core
workbox-core 中的 skipWaiting() 方法不會再新增 install 處理常式,相當於直接呼叫 self.skipWaiting()。
從現在起,請改用 self.skipWaiting(),因為 skipWaiting() 可能會在 Workbox v7 中移除。
workbox-precaching
- 如果網址對應至 HTTP 重新導向,則跨源 HTML 文件無法再用於滿足
workbox-precaching的導覽要求。這種情況通常不常見。 workbox-precaching在查詢指定要求的預先快取回應時,現在會忽略fbclid網址查詢參數。PrecacheController建構函式現在會採用具有特定屬性的物件做為參數,而非字串。這個物件支援下列屬性:cacheName(用途與傳遞至第 5 版建構函式的字串相同)、plugins(取代第 5 版的addPlugins()方法),以及fallbackToNetwork(取代傳遞至createHandler()和第 5 版 `createHandlerBoundToURL() 的類似選項)。PrecacheController的install()和activate()方法現在只會採用一個參數,應分別設為對應的InstallEvent或ActivateEvent。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 方法,預設為 'GET'。
- 如果您使用
setDefaultHandler(),且所有要求都是GET,則不需進行任何變更。 - 如果要求不是
GET(POST、PUT等),setDefaultHandler()將不再導致這些要求相符。
建構設定
workbox-build 和 workbox-cli 中 getManifest 和 injectManifest 模式的 mode 選項不應受到支援,因此已移除。這不適用於 workbox-webpack-plugin,因為該服務的 InjectManifest 外掛程式支援 mode。
建構工具需要 Node.js 10 以上版本
workbox-webpack-plugin、workbox-build 或 workbox-cli 不再支援 Node.js 10 以下版本。如果您執行的 Node.js 版本低於 v8,請將執行階段更新至支援的版本。
新改良功能
workbox-strategies
Workbox v6 推出新方法,讓第三方開發人員定義自己的 Workbox 策略。這可確保第三方開發人員能以完全符合需求的方式擴充 Workbox。
新策略基礎類別
在第 6 版中,所有 Workbox 策略類別都必須擴充新的 Strategy 基礎類別。所有內建策略都已重新編寫,以支援這項功能。
Strategy 基礎類別主要負責兩件事:
- 叫用所有策略處理常式通用的外掛程式生命週期回呼 (例如啟動、回應和結束時)。
- 建立「處理常式」執行個體,可管理策略處理的每個個別要求的狀態。
新的「處理常式」類別
我們之前有內部模組呼叫 fetchWrapper 和 cacheWrapper,顧名思義,這些模組會將各種擷取和快取 API 與掛鉤包裝到其生命週期中。這是目前允許外掛程式運作的機制,但不會向開發人員公開。
新的「處理常式」類別 StrategyHandler 會公開這些方法,讓自訂策略可以呼叫 fetch() 或 cacheMatch(),並自動叫用新增至策略例項的任何外掛程式。
這個類別也讓開發人員可以新增自己的自訂生命週期回呼,這些回呼可能與其策略相關,而且可以與現有的外掛程式介面「搭配運作」。
新外掛程式生命週期狀態
在 Workbox v5 中,外掛程式是無狀態的。也就是說,如果 /index.html 的請求同時觸發 requestWillFetch 和 cachedResponseWillBeUsed 回呼,這兩個回呼無法互相通訊,甚至不知道是由同一個請求觸發。
在第 6 版中,所有外掛程式回呼也會傳遞新的 state 物件。這個狀態物件對這個特定外掛程式物件和這個特定策略叫用 (即呼叫 handle()) 而言是唯一的。這可讓開發人員編寫外掛程式,其中一個回呼可根據同一個外掛程式中另一個回呼執行的動作,有條件地執行某些動作 (例如計算執行 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 檢查的實際標準郵件內文
{type: 'SKIP_WAITING'}呼叫postMessage(),以觸發skipWaiting()。 - 它會選擇正確的「等待中」Service Worker 來發布這則訊息,即使該 Service Worker 與註冊
workbox-window的 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 函式。如果要求是針對相同來源網址,則會設為 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 做為基礎。這項異動不會造成任何破壞性變更,且能讓這兩個模組長期以更一致的方式存取網路和快取。
預先快取現在會逐一處理項目,而非一次處理大量項目
workbox-precaching 已更新,因此預先快取資訊清單中一次只會要求及快取一個項目,而不是嘗試一次要求及快取所有項目 (讓瀏覽器自行決定如何限制)。
這應該會降低預先快取時發生 net::ERR_INSUFFICIENT_RESOURCES 錯誤的可能性,並減少預先快取與網頁應用程式同時發出的要求之間的頻寬爭用。
PrecacheFallbackPlugin 可讓您更輕鬆地設定離線備用方案
workbox-precaching 現在包含 PrecacheFallbackPlugin,可實作第 6 版新增的 handlerDidError 生命週期方法。
這樣一來,當回應無法使用時,就能輕鬆指定預先快取的網址做為特定策略的「備用」網址。外掛程式會為預先快取的網址正確建構快取鍵,包括任何必要的修訂版本參數。
以下範例說明如何使用這個方法,在 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 建立 Service Worker,而不是手動編寫 Service Worker,可以使用 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 提出問題,讓我們知道。