workbox-window
是 Workbox 模組中尚未詳細說明的模組,這是一組專門在 window
中執行的模組。本單元的目標如下:
- 協助開發人員找出服務工作者生命週期的關鍵時刻,簡化服務工作者註冊和更新程序,以便在這些時刻輕鬆回應。
- 避免開發人員犯下常見錯誤,例如在錯誤的範圍內註冊服務工作者。
- 簡化
window
和 Service Worker 範圍之間的訊息傳遞方式。
匯入並使用 workbox-window
您最常從 workbox-window
的匯出是 Workbox
類別,可用節點或從網頁中的 CDN 匯入。
建立本機組合
如果您的工具鍊包含 webpack 或 Rollup 等整合工具,就可以在本機建立 workbox-window
套件。
首先,請將 workbox-window
安裝為應用程式的正式依附元件:
npm install workbox-window --save
接著,您可以在應用程式 JavaScript 中,從 workbox-window
import
類別:
<script type="module">
import {Workbox} from 'workbox-window';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
雖然 workbox-window
相當小,但您可以使用動態 import
從網站的核心應用程式邏輯中分割 ,這樣就能縮減網頁主要套件的大小:
<script type="module">
if ('serviceWorker' in navigator) {
const {Workbox} = await import('workbox-window');
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
使用 CDN
雖然不是建議做法,但使用 workbox-window
的簡單方法是從 CDN 匯入:
<script type="module">
import {Workbox} from 'https://storage.googleapis.com/workbox-cdn/releases/6.2.0/workbox-window.prod.mjs';
if ('serviceWorker' in navigator) {
const wb = new Workbox('/sw.js');
wb.register();
}
</script>
請注意,上述範例中的 <script>
元素使用了 type="module"
屬性。如果您想在瀏覽器中使用靜態 import
陳述式,但不執行建構步驟,則必須使用此選項。支援 Service Worker 的所有主要瀏覽器也都支援 JavaScript 模組,因此您可以針對任何瀏覽器提供這段程式碼,因為舊版瀏覽器會忽略 type
屬性值為 "module"
的 <script>
元素。
註冊 Service Worker
向 workbox-window
註冊 Service Worker 會透過 Workbox
類別的 register
方法完成,如下所示:
import {Workbox} from 'workbox-window';
const wb = new Workbox('/sw.js');
wb.register();
這似乎與您使用 navigator.serviceWorker.register
自行註冊服務工作站相同。不過,Workbox.register
會等到 window
load
事件發生後,才註冊服務工作者。建議在涉及預先快取的情況下,避免可能會延遲頁面啟動的頻寬爭用情況。
在 window
和服務工作站範圍之間進行通訊
服務工作站的範圍與 window
分開,且只能存取 window
中可用的 API 子集。不過,window
和服務工作者之間可以進行通訊。workbox-window
可透過 workbox-window
模組的 messageSW
方法,讓兩個範圍之間的通訊更為輕鬆。
Workbox 使用特定格式傳送訊息,該訊息為具有下列屬性的物件:
type
是用於識別訊息的必要專屬字串。格式應使用大寫字母,並以底線分隔字詞 (例如CACHE_URLS
)。meta
是選用字串,代表傳送訊息的 Workbox 套件名稱,經常會省略。payload
是選用參數,代表您要傳送的資料。可以是任何資料類型。
以下舉例說明 messageSW
的運作方式,從 Service Worker 中的程式碼開始:
// sw.js
const SW_VERSION = '1.0.0';
self.addEventListener('message', (event) => {
if (event.data.type === 'GET_VERSION') {
event.ports[0].postMessage(SW_VERSION);
}
});
然後在網頁中加入下列程式碼:
const wb = new Workbox('/sw.js');
wb.register();
const swVersion = await wb.messageSW({type: 'GET_VERSION'});
console.log('Service Worker version:', swVersion);
許多情況下,在 Service Worker 與 window
之間通訊會很有用,例如在服務工作站更新可用時通知使用者。該方案仰賴名為 messageSkipWaiting
的 self.skipWaiting
特殊輔助方法,該方法會傳送 type
值為 SKIP_WAITING
的訊息。