本指南著重於 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,而且所有記錄和宣告都會從正式版本中移除,系統就會啟用偵錯記錄。 - 改善 Webpack 外掛程式。
workbox-webpack-plugin
可更密切地與 Webpack 建構程序整合,方便您在建構管道中預先快取所有資產時,使用零設定用途。
為了達成這些目標,並清除舊版介面中感到不安或造成反面模式的部分,請務必在 v3 版本中導入一些破壞性變更。
破壞性變更
建構設定
以下變更會影響所有建構工具 (workbox-build
、workbox-cli
、workbox-webpack-plugin
) 的行為,這些工具皆共用一組通用的設定選項。
'fastest'
處理常式名稱先前有效,且在設定runtimeCaching
時視為'staleWhileRevalidate'
的別名。此狀態已失效,開發人員應直接改用'staleWhileRevalidate'
。- 我們更新了數個
runtimeCaching.options
屬性名稱,並有其他參數驗證功能,如果使用無效的設定,會導致建構失敗。如需目前支援選項的清單,請參閱runtimeCaching
的說明文件。
工作箱-背景同步
maxRetentionTime
設定參數現在會解譯為分鐘數,而非毫秒。- 現在有代表佇列名稱的必要字串,這些字串必須在建構外掛程式或獨立類別時傳入,做為第一個參數。(這個引數先前是以選項屬性的形式傳入)。如需更新版 API 介面,請參閱說明文件。
workbox-broadcast-cache-update
- 現在有代表頻道名稱的必要字串,當您建構外掛程式或獨立類別時,必須傳入此字串做為第一個參數。
舉例來說,在 v2 中,您可以依照下列方式初始化外掛程式類別:
new workbox.broadcastCacheUpdate.BroadcastCacheUpdatePlugin({
channelName: 'cache-updates',
headersToCheck: ['etag'],
});
第 3 版中的同等用途如下:
new workbox.broadcastUpdate.Plugin('cache-updates', {headersToCheck: ['etag']});
如需更新版 API 介面,請參閱說明文件。
Workbox-build
- 根據預設,現在將使用選項
follow: true
(將追蹤符號連結) 和strict: true
(對「異常」錯誤的容忍度較低) 執行glob
模式比對。您可以在建構設定中設定globFollow: false
和/或globStrict: false
,藉此停用任一選項並返回先前的行為。 workbox-build
中的函式都會在傳回的回應中傳回額外屬性warnings
。現在允許在第 2 版中視為嚴重錯誤的情況,但可以透過warnings
(這個字串陣列) 回報。
在第 2 版中,您可以呼叫 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}`));
雖然您可以在 v3 中使用相同的程式碼,但建議您檢查並記錄任何 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
屬性,該屬性應為包含非重大警告資訊的字串陣列。
如果您是在 v2 中編寫自訂的 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;
});
};
的第 3 版相當於:
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: []};
};
getFileManifestEntries()
函式已重新命名為getManifest()
,且傳回的 promise 現在包含已預先快取網址的額外資訊。
第 2 版中的程式碼如下:
const manifestEntries = await workboxBuild.getFileManifestEntries({...});
可在第 3 版中重新編寫,如下所示:
const {manifestEntries, count, size, warnings} = await workboxBuild.getManifest({...});
// Use manifestEntries like before.
// Optionally, log the new info returned in count, size, warnings.
- 已移除
generateFileManifest()
函式。我們建議開發人員改為呼叫getManifest()
,然後透過回應以適當的格式將資料寫入磁碟。
工作箱-快取效期
- Plugin API 維持不變,大多數開發人員會使用此模式。不過,開發人員將 API 做為獨立類別使用的開發人員有重大的 API 變更。如需更新版 API 介面,請參閱說明文件。
workbox-cli
開發人員可透過 --help
標記,針對一組完整的支援參數執行 CLI。
- 已移除對二進位指令碼的
workbox-cli
別名支援功能。二進位檔現在只能以workbox
身分存取。 - v2 指令
generate:sw
和inject:manifest
在 v3 中已重新命名為generateSW
和injectManifest
。 - 在 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([...]);
的第 3 版相當於:
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.*
。 - 系統現在會依據先註冊的先進順序評估路徑。這是第 2 版使用的
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()
);
的第 3 版相當於:
workbox.routing.registerRoute(
new RegExp('^https://example.com/'),
workbox.strategies.networkFirst()
);
workbox.routing.registerRoute(
new RegExp('^/path/with/.*/wildcard'),
workbox.strategies.staleWhileRevalidate()
);
工作箱策略 (先前稱為 Workbox-runtime-caching)
workbox-runtime-caching
模組現已正式稱為workbox-strategies
,並在npm
發布,即採用新名稱。- 如果未一併提供快取名稱,在策略中使用快取到期時間就會失效。在 v2 中,可能的情況如下:
workboxSW.strategies.staleWhileRevalidate({
cacheExpiration: {maxEntries: 50},
});
這會導致預設快取中的項目過期,這是非預期的情況。在 v3 中,快取名稱為必填欄位:
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],
},
});
的第 3 版相當於:
const networkFirstStrategy = workbox.strategies.networkFirst({
cacheName: 'my-cache',
networkTimeoutSeconds: 5,
plugins: [
new workbox.expiration.Plugin({maxEntries: 50}),
new workbox.cacheableResponse.Plugin({statuses: [0, 200]}),
],
});
詳情請參閱「使用外掛程式」指南。
Workbox-SW
- 基本上,
workbox-sw
已改寫為輕量的「載入器」介面,該介面需要一些基本設定,並負責提取執行階段所需的其他模組。開發人員會與在全域命名空間中自動公開的現有執行個體互動,而不是建構WorkboxSW
類別的新執行個體。
第 2 版:
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
指令碼,系統就會自動在全域命名空間中以 workbox
形式提供可供使用的執行個體:
importScripts('<path to workbox-sw>/3.0.0/workbox-sw.js');
// workbox is implicitly created and ready for use.
workbox.routing.registerRoute(...);
skipWaiting
和clientsClaim
不再是傳遞至WorkboxSW
建構函式的選項。而已改為workbox.clientsClaim()
和workbox.skipWaiting()
方法。- 第 2 版建構函式支援的
handleFetch
選項,v3 不再支援。如果開發人員需要使用類似功能測試 Service Worker,而不叫用任何擷取處理常式,可以使用 Chrome 開發人員工具中的「略過網路」選項。
工作箱-webpack-外掛程式
此外掛程式已大幅重新編寫,在許多情況下,都可在「零設定」模式下使用。如需更新版 API 介面,請參閱說明文件。
- API 現在公開了
GenerateSW
和InjectManifest
兩種類別。這會讓使用者明確切換模式,與 v2 行為的切換則是根據swSrc
的存在而變更。 - 根據預設,系統會預先快取 Webpack 編譯管道中的資產,不再需要設定
globPatterns
。如要繼續使用globPatterns
,唯一的原因是您需要預先快取未納入 Webpack 版本中的資產。一般而言,當您遷移至 v3 外掛程式時,請先移除先前的所有以glob
為基礎的設定,並只在必要時重新加入。
取得協助
我們預期大部分的遷移作業都很簡單。如果您遇到本指南未涵蓋的問題,請在 GitHub 上建立問題告訴我們。