workbox-sw
模块提供了一种极其简单的方法来启动和运行 Workbox 模块,简化了 Workbox 模块的加载,并且提供了一些简单的辅助方法。
您可以通过我们的 CDN 使用 workbox-sw
,也可以将其用于您自己的服务器上的一组工作箱文件。
通过 CDN 使用 Workbox SW
要开始使用此模块,最简单的方法是通过 CDN。您只需将以下内容添加到 Service Worker:
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
会检测到这种情况并加载该模块,然后再使其可用。您可以在开发者工具的“Network”标签页中看到发生这种情况。
这些文件将由浏览器缓存,以供日后离线使用。
使用本地 Workbox 文件,而非 CDN
如果您不想使用 CDN,也可以轻松切换到托管在您自己的网域上的 Workbox 文件。
最简单的方法是通过 workbox-cli
的 copyLibraries
命令获取文件,然后通过 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}));
}
});
强制使用调试 build 或正式版 build
所有 Workbox 模块都包含两个 build:一个是调试 build(包含日志记录和额外的类型检查),另一个是去除日志记录和类型检查的正式版 build。
默认情况下,workbox-sw
将针对 localhost 上的网站使用调试 build;但对于任何其他来源,则使用正式版 build。
如果要强制使用调试 build 或正式版 build,您可以设置 debug
配置选项:
workbox.setConfig({
debug: true,
});
使用 import 语句转换代码以使用 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-background-sync
npm 软件包导出的所有模块都可以在 workbox.backgroundSync.*
上找到。
例如,以下代码使用 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
重写的相同代码(请注意,只有 import 语句发生了变化,逻辑没有发生变化):
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]})],
})
);