從 Workbox v2 遷移至第 3 版

本指南主要介紹 Workbox v3 中導入的破壞性變更,並舉例說明從 Workbox v2 設定升級時需要進行哪些變更。

如果您目前使用舊版 sw-precache/sw-toolbox 組合,且希望是第一次改用 Workbox,請參閱這份不同的遷移指南,或許能幫上忙。

v3 背景

Workbox 的 v3 版本代表現有程式碼集的重大重構作業。主要目標是:

  • 縮小 Workbox 的大小。下載及執行的 Service Worker 執行階段程式碼數量已減少。系統只會在執行階段匯入您使用的特定功能的程式碼,不會讓所有人都能加入單體式套件。
  • Workbox 具備 CDN我們提供以 Google Cloud Storage 為基礎的 CDN 代管服務,這是存取 Workbox 執行階段程式庫的標準選項,可讓您更輕鬆地開始使用 Workbox。
  • 改良偵錯功能和記錄。偵錯與記錄功能已大幅提升。凡是從 localhost 來源使用 Workbox,且所有記錄和斷言都會從實際工作環境版本中移除,都會預設啟用偵錯記錄。 Workbox v3 提供的偵錯記錄功能範例。
  • 改良的 webpack 外掛程式。workbox-webpack-plugin 更緊密地整合 webpack 建構程序,因此當您要預先快取建構管道中的所有資產時,不必進行任何設定。

如要達成這些目標,並清除先前介面上會令人不悅或會導致反面模式的一些部分,必須在 v3 版本中導入多項破壞性變更。

破壞性變更

版本設定

以下變更會影響所有共用工具 (workbox-buildworkbox-cliworkbox-webpack-plugin) 的行為。這些工具都共用一組常用設定選項。

  • 'fastest' 處理常式名稱先前為有效名稱,且在設定 runtimeCaching 時視為 'staleWhileRevalidate' 的別名。此按鈕已失效,開發人員應直接改用 'staleWhileRevalidate'
  • 多個 runtimeCaching.options 屬性名稱已更新,且有額外的參數驗證功能會在使用無效設定時造成建構失敗。如需目前支援的選項清單,請參閱 runtimeCaching說明文件

workbox-background-sync

  • 系統現在會將 maxRetentionTime 設定參數解讀為分鐘數,而非毫秒數。
  • 現在有一個代表佇列名稱的必要字串,在建構外掛程式或獨立類別時,必須做為第一個參數傳入。(先前是以選項屬性的形式傳入)。如需更新後的 API 介面,請參閱說明文件

workbox-broadcast-cache-update

  • 現在有代表頻道名稱的必要字串,在建構外掛程式或獨立類別時,必須做為第一個參數傳入。

例如,在第 2 版中,您會初始化外掛程式類別,如下所示:

new workbox.broadcastCacheUpdate.BroadcastCacheUpdatePlugin({
  channelName: 'cache-updates',
  headersToCheck: ['etag'],
});

第 3 版中的對等用法如下:

new workbox.broadcastUpdate.Plugin('cache-updates', {headersToCheck: ['etag']});

如需更新後的 API 介面,請參閱說明文件

workbox-build

  • 根據預設,glob 模式比對現在會使用「選項」follow: true (後續符號連結) 和 strict: true (較不容許「異常」錯誤) 執行。您可以在建構設定中設定 globFollow: false 和/或 globStrict: false,藉此停用兩者並返回先前的行為。
  • workbox-build 中的函式都會在其傳回的回應中傳回額外的屬性 warnings。部分在第 2 版中被視為嚴重錯誤的部分,現已允許,但透過 warnings 回報,也就是字串陣列。

在 v2 中,您可以呼叫 generateSW,例如:

const workboxBuild = require('workbox-build');

workboxBuild.generateSW({...})
  .then(({count, size}) => console.log(`Precached ${count} files, totaling ${size} bytes.`))
  .catch((error) => console.error(`Something went wrong: ${error}`));

雖然您可以在第 3 版中使用相同程式碼,但建議您檢查是否有任何 warnings 並加以記錄:

const workboxBuild = require('workbox-build');

workboxBuild.generateSW({...})
  .then(({count, size, warnings}) => {
    for (const warning of warnings) {
      console.warn(warning);
    }
    console.log(`Precached ${count} files, totalling ${size} bytes.`);
  })
  .catch((error) => console.error(`Something went wrong: ${error}`));
  • 在第 2 版中自行編寫自訂 ManifestTransform 函式的開發人員,必須在物件中傳回資訊清單陣列 (也就是應使用 return {manifest: manifestArray};,而不是 return manifestArray;)。m 此方法可讓外掛程式加入選用的 warnings 屬性,該屬性應為含有非嚴重警告資訊的字串陣列。

如果您在第 2 版中編寫自訂 ManifestTransform,則程式碼如下:

const cdnTransform = manifestEntries => {
  return manifestEntries.map(entry => {
    const cdnOrigin = 'https://example.com';
    if (entry.url.startsWith('/assets/')) {
      entry.url = cdnOrigin + entry.url;
    }
    return entry;
  });
};

等於:

const cdnTransform = manifestEntries => {
  const manifest = manifestEntries.map(entry => {
    const cdnOrigin = 'https://example.com';
    if (entry.url.startsWith('/assets/')) {
      entry.url = cdnOrigin + entry.url;
    }
    return entry;
  });
  return {manifest, warnings: []};
};

v2 中的程式碼如下所示:

const manifestEntries = await workboxBuild.getFileManifestEntries({...});

可在 v3 中重新編寫為:

const {manifestEntries, count, size, warnings} = await workboxBuild.getManifest({...});

// Use manifestEntries like before.
// Optionally, log the new info returned in count, size, warnings.
  • 移除 generateFileManifest() 函式。建議開發人員改為呼叫 getManifest(),並透過回應以適當格式將資料寫入磁碟。

workbox-cache-expiration

  • 外掛程式 API 維持不變,多數開發人員都會使用這種模式。不過,如果開發人員將這種 API 做為獨立類別使用,會有重大的 API 變更受到影響。如需更新後的 API 介面,請參閱說明文件

workbox-cli

開發人員可以透過 --help 標記執行 CLI,以取得完整的支援參數。

  • 已停止支援二進位指令碼的 workbox-cli 別名。二進位檔現在只能以 workbox 的形式存取。
  • 在 v2 中,v2 指令 generate:swinject:manifest 已重新命名為 generateSWinjectManifest
  • 在 v2 中,預設設定檔 (在未提供設定檔時使用) 會假設為目前目錄中的 workbox-cli-config.js。在第 3 版中則為 workbox-config.js

整體來說,也就是在第 2 版中:

$ workbox inject:manifest

會執行「插入資訊清單」建構程序,使用從 workbox-cli-config.js 和 v3 讀取的設定:

$ workbox injectManifest

這麼做會相同,但請從 workbox-config.js 讀取設定。

工作箱預先快取

  • precache() 方法先前已執行快取修改及設定轉送作業,以提供快取項目。現在,precache() 只會修改快取項目,並且已公開新的方法 addRoute(),以註冊提供這些快取回應的路徑。如果開發人員想要先前的雙層功能,可以改用 precacheAndRoute()
  • 許多透過 WorkboxSW 建構函式設定的選項,現在會做為 workbox.precaching.precacheAndRoute([...], options) 中的 options 參數傳遞。如未設定這些選項,請參閱參考說明文件
  • 根據預設,系統會自動檢查缺少副檔名的網址,比對網址是否包含 .html 副檔名。例如,如果要求 /path/to/index 要求 (不會友善快取),且有 /path/to/index.html 的友善快取項目,系統會使用該友善快取項目。開發人員可以在將選項傳遞至 workbox.precaching.precacheAndRoute() 時設定 {cleanUrls: false},藉此停用這個新行為。
  • 系統不會再自動設定「workbox-broadcast-update」來公告友善快取資產的快取更新。

以下是第 2 版中的程式碼:

const workboxSW = new self.WorkboxSW({
  directoryIndex: 'index.html',
  ignoreUrlParametersMatching: [/^utm_/],
  precacheChannelName: 'precache-updates',
});
workboxSW.precache([...]);

等於:

workbox.precaching.addPlugins([
    new workbox.broadcastUpdate.Plugin('precache-updates')
]);

workbox.precaching.precacheAndRoute([...], {
  cleanUrls: false,
  directoryIndex: 'index.html',
  ignoreUrlParametersMatching: [/^utm_/],
});

工作箱路徑

  • 開發人員先前透過 WorkboxSW 物件的 workbox.router.* 命名空間使用 workbox-routing 時,必須改用新的命名空間 workbox.routing.*
  • 系統現在會按照首次登錄的勝出順序評估路徑。這是在 v2 中使用的 Route 評估順序「相反」,系統會優先採用上次註冊的 Route
  • ExpressRoute 類別和支援「Express-style」已移除萬用字元。這會大幅縮減 workbox-routing 的大小。用來當做 workbox.routing.registerRoute() 第一個參數的字串現在會視為完全比對。萬用字元或部分比對結果應由 RegExp 處理,且使用任何與部分或所有要求網址相符的 RegExp 都會觸發路徑。
  • Router 類別的 addFetchListener() 輔助方法已移除。開發人員可以明確新增自己的 fetch 處理常式,或使用 workbox.routing 提供的介面,間接為這些處理常式建立 fetch 處理常式。
  • 已移除 registerRoutes()unregisterRoutes() 方法。在單一 Route 上運作的方法版本不會變更,而開發人員需要一次註冊或取消登錄多個路徑的開發人員,應改為對 registerRoute()unregisterRoute() 進行一系列的呼叫。

以下是第 2 版中的程式碼:

const workboxSW = new self.WorkboxSW();

workboxSW.router.registerRoute(
  '/path/with/.*/wildcard/',
  workboxSW.strategies.staleWhileRevalidate()
);

workboxSW.router.registerRoute(
  new RegExp('^https://example.com/'),
  workboxSW.strategies.networkFirst()
);

等於:

workbox.routing.registerRoute(
  new RegExp('^https://example.com/'),
  workbox.strategies.networkFirst()
);

workbox.routing.registerRoute(
  new RegExp('^/path/with/.*/wildcard'),
  workbox.strategies.staleWhileRevalidate()
);

Workbox-strategies (先前稱為 Workbox-runtime-caching)

  • workbox-runtime-caching 模組現已正式名稱為 workbox-strategies,並已於 npm 發布,且採用新名稱。
  • 在未提供快取名稱的情況下,在策略中使用快取效期已失效。在第 2 版中,可能的情況如下:
workboxSW.strategies.staleWhileRevalidate({
  cacheExpiration: {maxEntries: 50},
});

這會導致預設快取中的項目即將到期,但這是非預期的結果。在第 3 版中,快取名稱 「 」為必填欄位:

workboxSW.strategies.staleWhileRevalidate({
  cacheName: 'my-cache',
  plugins: [new workbox.expiration.Plugin({maxEntries: 50})],
});
  • cacheWillMatch 生命週期方法已重新命名為 cachedResponseWillBeUsed。除非開發人員自行編寫回應 cacheWillMatch 的外掛程式,否則這種情況不會造成開發人員明顯的變更。
  • 設定策略時,指定外掛程式的語法已變更。每個外掛程式都必須在策略設定的 plugins 屬性中明確列出。

以下是第 2 版中的程式碼:

const workboxSW = new self.WorkboxSW();

const networkFirstStrategy = workboxSW.strategies.networkFirst({
  cacheName: 'my-cache',
  networkTimeoutSeconds: 5,
  cacheExpiration: {
    maxEntries: 50,
  },
  cacheableResponse: {
    statuses: [0, 200],
  },
});

等於:

const networkFirstStrategy = workbox.strategies.networkFirst({
  cacheName: 'my-cache',
  networkTimeoutSeconds: 5,
  plugins: [
    new workbox.expiration.Plugin({maxEntries: 50}),
    new workbox.cacheableResponse.Plugin({statuses: [0, 200]}),
  ],
});

詳情請參閱使用外掛程式指南。

工作箱 Sw

  • workbox-sw 實際上已重寫為輕量的「載入器」介面,可啟用一些基本設定,並負責提取執行階段所需的其他模組。開發人員會與進行全域命名空間自動公開的現有執行個體互動,而不是建構 WorkboxSW 類別的新例項。

先前為 v2 版本:

importScripts('<path to workbox-sw>/importScripts/workbox-sw.prod.v2.1.3.js');

const workbox = new WorkboxSW({
  skipWaiting: true,
  clientsClaim: true,
  // etc.
});

workbox.router.registerRoute(...);

在 v3 中,您只需要匯入 workbox-sw.js 指令碼,1 個立即可用的執行個體就會自動在全域命名空間中以 workbox 的形式提供:

importScripts('<path to workbox-sw>/3.0.0/workbox-sw.js');

// workbox is implicitly created and ready for use.
workbox.routing.registerRoute(...);
  • skipWaitingclientsClaim 不再是傳遞至 WorkboxSW 建構函式的選項。而是改為 workbox.clientsClaim()workbox.skipWaiting() 方法。
  • 第 2 版建構函式先前支援的 handleFetch 選項,不再支援第 3 版。如果開發人員需要在不叫用任何擷取處理常式的情況下,使用類似功能測試 Service Worker,可以使用「網路略過」選項。
Chrome 開發人員工具的「略過網路」選項。

workbox-webpack-plugin

外掛程式已大幅重寫,在許多情況下,都能用「零設定」方式使用模式。如需更新後的 API 介面,請參閱說明文件

  • API 現在會顯示兩個類別:GenerateSWInjectManifest。這使得在明確模式之間進行切換,而第 2 版的行為會因為是否出現 swSrc 而變更行為。
  • 根據預設,系統會預先快取 Webpack 編譯管道中的資產,不再需要設定 globPatterns。您必須預先快取未包含在 webpack 版本中未包含的資產,才能繼續使用 globPatterns。一般來說,如要遷移至 v3 外掛程式,建議您先移除所有先前的 glob 型設定,並只在有需要時重新加入。

取得說明

我們預期大多數的遷移作業都較為簡單。如果您遇到本指南未提及的問題,請在 GitHub 上開啟問題通知我們。