工作箱 SW

workbox-sw 模組可讓您輕鬆快速地開始使用 Workbox 模組,並簡化 Workbox 模組的載入作業,並提供幾個簡單的輔助方法。

您可以透過我們的 CDN 使用 workbox-sw,或是將其與您自己的伺服器上的一組 Workbox 檔案搭配使用。

透過 CDN 使用 Workbox SW

開始使用這個模組最簡單的方法,就是透過 CDN。您只需要將下列項目新增至服務工作站:

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

如此一來,您的 Service Worker 中就有 workbox 命名空間,可提供所有 Workbox 模組的存取權。

workbox.precaching.*
workbox.routing.*
etc

開始使用額外模組時,會發生一些神奇效果。

首次參照模組時,workbox-sw 會偵測此模組並載入模組,然後再提供該模組。您可以在開發人員工具的「網路」分頁中查看這項動作。

在開發人員工具中載入 Workbox 程式庫

瀏覽器會快取這些檔案,以供日後離線使用。

使用本機 Workbox 檔案,不要使用 CDN

如果不想使用 CDN,您可以輕鬆改用自己網域上代管的 Workbox 檔案。

最簡單的方法是透過 workbox-clicopyLibraries 指令取得檔案,然後使用 modulePathPrefix 設定選項告知 workbox-sw 可以在哪裡找到這些檔案。

如果您將檔案放在 /third_party/workbox-vX.Y.Z/ 之下,會想要使用它們:

importScripts('/third_party/workbox-vX.Y.Z/workbox-sw.js');

workbox.setConfig({
  modulePathPrefix: '/third_party/workbox-vX.Y.Z/',
});

避免非同步匯入

基本上,第一次載入新模組時,需要使用對應至對應 JavaScript 檔案的路徑 (由 CDN 代管或本機網址) 呼叫 importScripts()。無論是哪一種情況,都套用了重要限制:對 importScripts() 的隱含呼叫只能在 Service Worker 的 install 處理常式中發生,「或是」在 Service Worker 指令碼的初始執行同步期間發生。

為了避免違反這項限制,最佳做法是參照任何事件處理常式或非同步函式之外的各種 workbox.* 命名空間。

舉例來說,下列頂層 Service Worker 程式碼沒有問題:

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

// This will work!
workbox.routing.registerRoute(
  ({request}) => request.destination === 'image',
  new workbox.strategies.CacheFirst()
);

但如果您未在 Service Worker 的其他位置參照 workbox.strategies,則下列程式碼可能有問題:

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

self.addEventListener('fetch', event => {
  if (event.request.url.endsWith('.png')) {
    // Oops! This causes workbox-strategies.js to be imported inside a fetch handler,
    // outside of the initial, synchronous service worker execution.
    const cacheFirst = new workbox.strategies.CacheFirst();
    event.respondWith(cacheFirst.handle({request: event.request}));
  }
});

如果您需要編寫程式碼可能會失敗,可以使用 workbox.loadModule() 方法在事件處理常式外明確觸發 importScripts() 呼叫:

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

// This will trigger the importScripts() for workbox.strategies and its dependencies:
workbox.loadModule('workbox-strategies');

self.addEventListener('fetch', event => {
  if (event.request.url.endsWith('.png')) {
    // Referencing workbox.strategies will now work as expected.
    const cacheFirst = new workbox.strategies.CacheFirst();
    event.respondWith(cacheFirst.handle({request: event.request}));
  }
});

或者,您也可以在事件處理常式外建立相關命名空間的參照,然後在之後使用該參照:

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

// This will trigger the importScripts() for workbox.strategies and its dependencies:
const {strategies} = workbox;

self.addEventListener('fetch', event => {
  if (event.request.url.endsWith('.png')) {
    // Using the previously-initialized strategies will work as expected.
    const cacheFirst = new strategies.CacheFirst();
    event.respondWith(cacheFirst.handle({request: event.request}));
  }
});

強制使用偵錯版本或正式版

所有 Workbox 模組都提供兩種版本:偵錯版本包含記錄和額外類型檢查,以及移除記錄和類型檢查的正式版本。

根據預設,workbox-sw 會針對 localhost 上的網站使用偵錯版本,但任何其他來源都會使用正式環境版本。

如要強制偵錯或正式版本,可以設定 debug 設定選項:

workbox.setConfig({
  debug: true,
});

使用匯入陳述式轉換程式碼,以便使用 workbox-sw

使用 workbox-sw 載入 Workbox 時,可透過全域 workbox.* 命名空間存取所有 Workbox 套件。

如果您的程式碼範例使用 import 陳述式,且想轉換成使用 workbox-sw,只需載入 workbox-sw,並將所有 import 陳述式替換為參照全域命名空間上這些模組的本機變數即可。

這能夠正常運作,因為每個發布至 npm 的 Workbox Service Worker 套件也會透過名稱的 camelCase 版本在全域 workbox 命名空間取得 (例如,從 workbox-precaching npm 套件匯出的所有模組都可以在 workbox.precaching.* 中找到)。您可以在 workbox.backgroundSync.* 中找到從 workbox-background-sync npm 套件匯出的所有模組。

例如,以下程式碼使用 import 陳述式來參照 Workbox 模組:

import {registerRoute} from 'workbox-routing';
import {CacheFirst} from 'workbox-strategies';
import {CacheableResponse} from 'workbox-cacheable-response';

registerRoute(
  ({request}) => request.destination === 'image',
  new CacheFirst({
    plugins: [new CacheableResponsePlugin({statuses: [0, 200]})],
  })
);

以下為使用 workbox-sw 修改的程式碼 (請注意,只有匯入陳述式已變更,且未調整邏輯):

importScripts(
  'https://storage.googleapis.com/workbox-cdn/releases/6.4.1/workbox-sw.js'
);

const {registerRoute} = workbox.routing;
const {CacheFirst} = workbox.strategies;
const {CacheableResponse} = workbox.cacheableResponse;

registerRoute(
  ({request}) => request.destination === 'image',
  new CacheFirst({
    plugins: [new CacheableResponsePlugin({statuses: [0, 200]})],
  })
);