從 Workbox v3 遷移至 v4

本指南著重於 Workbox v4 引入的破壞性變更,並舉例說明從 Workbox v3 升級時,您需要進行哪些變更。

破壞性變更

Workbox 預先快取

已更新預先快取項目的命名慣例。現在,如果是網址需要修訂資訊的項目 (也就是預先快取資訊清單中含有 revision 欄位的項目),系統會將版本資訊,儲存為快取金鑰的一部分,然後附加在原始網址附加的特殊 __WB_REVISION__ 網址查詢參數中。(先前使用 IndexedDB,這項資訊會與快取金鑰分開儲存)。

開發人員利用 workbox.precaching.precacheAndRoute() 預先快取;這是最常見的用途,因此無須變更 Service Worker 設定;在升級至 Workbox v4 後,使用者的快取資產會自動改用新的快取金鑰格式,日後我們也將繼續按照先前的方式提供預先快取資源。

直接使用快取金鑰

部分開發人員可能需要在 workbox.precaching.precacheAndRoute() 環境外直接存取友善快取項目。舉例來說,當系統無法從網路擷取實際圖片時,您可以預先快取最終圖片做為「備用」回應。

如果您透過這種方式使用預先快取素材資源 (從 Workbox v4 開始),就需要執行額外步驟,才能將原始網址轉譯成對應的快取金鑰,而該金鑰可用於讀取快取項目。只要呼叫 workbox.precaching.getCacheKeyForURL(originURL) 即可進行確認。

舉例來說,如果您知道 'fallback.png' 是預先快取:

const imageFallbackCacheKey =
  workbox.precaching.getCacheKeyForURL('fallback.png');

workbox.routing.setCatchHandler(({event}) => {
  switch (event.request.destination) {
    case 'image':
      return caches.match(imageFallbackCacheKey);
      break;
    // ...other fallback logic goes here...
  }
});

清除舊的預先快取資料

我們對 Workbox v4 中對預先快取所做的變更,表示與先前 Workbox 版本建立的較舊預先快取並不相容。根據預設,設定不會改變,而且從 Workbox v3 升級至 Workbox v4 後,會產生兩個所有預先快取資源的副本。

為避免這種情況,您可以直接呼叫 workbox.precaching.cleanupOutdatedCaches() 給 Service Worker,或者在 GenerateSW 模式下使用建構工具時,設定新的 cleanupOutdatedCaches: true 選項。由於快取清理邏輯是在快取命名慣例下運作以找出較舊的預先快取,而且開發人員可以選擇覆寫這些慣例,因此我們基於安全考量而停用,而且在預設情況下不會啟用這項功能。

如果開發人員在使用這個選項時遇到任何問題,例如導致刪除作業誤報,請告訴我們

參數大寫

可傳遞給 workbox.precaching.precacheAndRoute()workbox.precaching.addRoute() 的兩個選用參數已重新命名,以實現整體大小寫慣例。ignoreUrlParametersMatching 現在是 ignoreURLParametersMatching,而 cleanUrls 現在是 cleanURLs

工作盒策略

workbox-strategies 中,建立處理常式執行個體的方式有兩種,做法大致相同。我們將淘汰工廠方法,改為明確呼叫策略的建構函式。

// This factory method syntax has been deprecated:
const networkFirstStrategy = workbox.strategies.networkFirst({...});

// Instead, use the constructor directly:
// (Note that the class name is Uppercase.)
const networkFirstStrategy = new workbox.strategies.NetworkFirst({...});

雖然工廠方法語法在第 4 版中仍然有效,但使用這個語法會記錄警告,我們也鼓勵開發人員在日後第 5 版中移除前,先進行遷移。

Workbox-background-sync

經過重新編寫 workbox.backgroundSync.Queue 類別,讓開發人員能更靈活地掌控要求新增至佇列及重播的方式。

在第 3 版中,Queue 類別提供一種將要求新增至佇列的單一方式 (addRequest() 方法),但並沒有修改佇列或移除要求的方式。

第 4 版已移除 addRequests() 方法,並新增了下列類似陣列的方法:

  • pushRequest()
  • popRequest()
  • shiftRequest()
  • unshiftRequest()

在第 3 版中,Queue 類別也接受多個回呼,方便您觀察要求重播的時間 (requestWillEnqueuerequestWillReplayqueueDidReplay),但大多數開發人員發現除了觀察之外,還想控制佇列的重播方式,包括動態修改、重新排序,甚至取消個別要求。

在第 4 版中,這些回呼已移除,改用單一 onSync 回呼,每當瀏覽器發出重播時就會叫用此回呼。根據預設,onSync 回呼會叫用 replayRequests(),但如果您需要進一步控制重播程序,可以使用上述類似陣列的方法重播佇列。

以下是自訂重播邏輯的範例:

const queue = new workbox.backgroundSync.Queue('my-queue-name', {
  onSync: async ({queue}) => {
    let entry;
    while ((entry = await this.shiftRequest())) {
      try {
        await fetch(entry.request);
      } catch (error) {
        console.error('Replay failed for request', entry.request, error);
        await this.unshiftRequest(entry);
        return;
      }
    }
    console.log('Replay complete!');
  },
});

同樣地,workbox.backgroundSync.Plugin 類別接受與 Queue 類別相同的引數 (因為會在內部建立 Queue 例項),因此變更方式相同。

工作方塊到期時間

npm 套件已重新命名為 workbox-expiration,以符合其他模組的命名慣例。這個套件的功能等同於已淘汰的舊版 workbox-cache-expiration 套件

工作箱廣播-更新

npm 套件已重新命名為 workbox-broadcast-update,以符合其他模組的命名慣例。這個套件的功能等同於已淘汰的舊版 workbox-broadcast-cache-update 套件

Workbox-core

在 Workbox v3 中,記錄層級詳細程度可以透過 workbox.core.setLogLevel() 方法控制,請傳遞 workbox.core.LOG_LEVELS 列舉的其中一個值。您也可以透過 workbox.core.logLevel 讀取目前的記錄層級。

由於所有新式開發人員工具現在都具備豐富的記錄篩選功能,我們已在 Workbox v4 中移除上述所有功能 (請參閱 Chrome 開發人員工具的篩選控制台輸出內容一文)。

工作盒

先前在 workbox 命名空間中直接公開的兩個方法 (對應至 workbox-sw 模組) 已改為移至 workbox.coreworkbox.skipWaiting() 已成為 workbox.core.skipWaiting(),同理,workbox.clientsClaim() 已成為 workbox.core.clientsClaim()

建構工具設定

可傳入 Workbox-cli、workbox-build 或 workbox-webpack-plugin 的某些選項命名方式已經變更。每當選項名稱中使用「Url」,系統就會將其淘汰並改用「URL」。也就是說,建議使用下列選項名稱:

  • dontCacheBustURLsMatching
  • ignoreURLParametersMatching
  • modifyURLPrefix
  • templatedURLs

這些選項名稱的「網址」變化版本在 v4 中仍然有效,但會出現警告訊息。我們建議開發人員在第 5 版之前遷移。

新功能

工作盒視窗

新的 workbox-window 模組可簡化服務工作處理程序的註冊和偵測更新程序,並為在 Service Worker 中執行的程式碼與在網頁應用程式 window 結構定義中執行的程式碼提供標準通訊方式。

雖然使用 workbox-window 是選擇性步驟,但我們還是希望開發人員覺得實用,並考慮遷移部分手寫邏輯,以在適當情況下使用。如要進一步瞭解如何使用 workbox-window,請參閱模組指南

遷移範例

這份提取要求會提供從 Workbox v3 遷移至 v4 的實際案例。

取得協助

我們預期大部分的遷移作業都很直接,如果遇到本指南未涵蓋的問題,請前往 GitHub 開啟問題回報給我們。