从 Workbox v3 迁移到 v4

本指南重点介绍 Workbox v4 中引入的破坏性更改,并通过示例说明了从 Workbox v3 升级时需要做出哪些更改。

重大更改

工作框预缓存

已更新预缓存条目的命名惯例。现在,对于网址需要修订信息的条目(即预缓存清单中包含 revision 字段的条目),该版本控制信息将存储在缓存键中,并存储在附加到原始网址的特殊 __WB_REVISION__ 网址查询参数中。(以前,此类信息使用 IndexedDB 与缓存键分开存储)。

如果开发者通过 workbox.precaching.precacheAndRoute()(最常见的用例)利用预缓存,则无需对其 Service Worker 配置进行任何更改;升级到 Workbox v4 后,用户的缓存资源将自动迁移到新的缓存键格式,今后,预缓存资源将继续以与之前相同的方式提供。

直接使用缓存键

某些开发者可能需要在 workbox.precaching.precacheAndRoute() 的上下文之外直接访问预缓存条目。例如,您可以预缓存某张图片,以便在无法从网络提取实际图片时将其用作“后备”响应。

如果您以这种方式使用预缓存的资源,则从 Workbox v4 开始,您将需要执行一个额外步骤,以将原始网址转换为可用于读取缓存条目的相应缓存键。您可以通过调用 workbox.precaching.getCacheKeyForURL(originURL) 来完成此操作。

例如,如果您知道 'fallback.png' 已预缓存:

const imageFallbackCacheKey =
  workbox.precaching.getCacheKeyForURL('fallback.png');

workbox.routing.setCatchHandler(({event}) => {
  switch (event.request.destination) {
    case 'image':
      return caches.match(imageFallbackCacheKey);
      break;
    // ...other fallback logic goes here...
  }
});

清理旧的预缓存数据

在 Workbox v4 中对预缓存所做的更改意味着,先前版本的 Workbox 创建的旧预缓存不兼容。默认情况下,它们会保持原样,如果您从 Workbox v3 升级到 Workbox v4,最终会获得所有预缓存资源的两个副本。

为避免这种情况,您可以直接向 Service Worker 添加对 workbox.precaching.cleanupOutdatedCaches() 的调用,或者在 GenerateSW 模式下使用构建工具时设置新的 cleanupOutdatedCaches: true 选项。因为缓存清理逻辑按照缓存命名规范运行以查找较旧的预缓存,而且开发者确实可以选择覆盖这些规范,所以为保护安全性,我们不保证默认启用此功能。

如果开发者在使用该工具时遇到任何问题(例如关于删除的误报),欢迎告知我们

参数大写

我们重命名了两个可传递到 workbox.precaching.precacheAndRoute()workbox.precaching.addRoute()可选参数,以使我们的总体大写规范化。ignoreUrlParametersMatching 现已更名为 ignoreURLParametersMatchingcleanUrls 现已更名为 cleanURLs

工作框策略

workbox-strategies 中创建处理程序实例有两种大致等同的方法。我们将弃用工厂方法,取而代之的是显式调用策略的构造函数。

// This factory method syntax has been deprecated:
const networkFirstStrategy = workbox.strategies.networkFirst({...});

// Instead, use the constructor directly:
// (Note that the class name is Uppercase.)
const networkFirstStrategy = new workbox.strategies.NetworkFirst({...});

虽然出厂方法语法在 v4 中仍然有效,但使用该方法会记录警告,我们建议开发者在未来的 v5 版本取消支持之前进行迁移。

工作框后台同步

重写了 workbox.backgroundSync.Queue,以便让开发者更灵活地控制如何向队列添加请求及如何重放请求。

在 v3 中,Queue 类只有一种向队列添加请求的方法(addRequest() 方法),但它无法以任何方式修改队列或移除请求。

v4 中已移除 addRequests() 方法,并添加了以下类数组方法:

  • pushRequest()
  • popRequest()
  • shiftRequest()
  • unshiftRequest()

在 v3 中,Queue 类还接受了多个回调,可让您观察请求何时重放(requestWillEnqueuerequestWillReplayqueueDidReplay),但大多数开发者发现,除了观察之外,他们还希望控制队列的重放方式,包括动态修改、重新排序甚至取消单个请求的能力。

在 v4 中,这些回调已被移除,取而代之的是单个 onSync 回调,该回调会在浏览器每次尝试重放时调用。默认情况下,onSync 回调将调用 replayRequests(),但如果您需要更好地控制重放过程,可以使用上面列出的类数组方法,按照自己的喜好重放队列。

以下是自定义重放逻辑的示例:

const queue = new workbox.backgroundSync.Queue('my-queue-name', {
  onSync: async ({queue}) => {
    let entry;
    while ((entry = await this.shiftRequest())) {
      try {
        await fetch(entry.request);
      } catch (error) {
        console.error('Replay failed for request', entry.request, error);
        await this.unshiftRequest(entry);
        return;
      }
    }
    console.log('Replay complete!');
  },
});

同样,workbox.backgroundSync.Plugin 类接受与 Queue 类相同的实参(因为它在内部创建 Queue 实例),因此以同样的方式进行更改。

工作框到期

npm 软件包已重命名为 workbox-expiration,与其他模块使用的命名惯例一致。此软件包的功能等同于现已废弃的旧版 workbox-cache-expiration 软件包

工作框广播更新

npm 软件包已重命名为 workbox-broadcast-update,与其他模块使用的命名惯例一致。此软件包的功能等同于现已废弃的旧版 workbox-broadcast-cache-update 软件包

工作框核心

在 Workbox v3 中,日志级别的详细程度可以通过 workbox.core.setLogLevel() 方法控制,该方法需要传递 workbox.core.LOG_LEVELS 枚举中的一个值。您还可以通过 workbox.core.logLevel 读取当前日志级别。

在 Workbox v4 中,由于所有现代开发者工具现在都附带了丰富的日志过滤功能(请参阅 Chrome 开发者工具的过滤控制台输出),因此所有这些都已移除。

工作区-SW

之前直接在 workbox 命名空间(对应于 workbox-sw 模块)上提供的两个方法已移至 workbox.coreworkbox.skipWaiting() 已变为 workbox.core.skipWaiting(),同样,workbox.clientsClaim() 已变为 workbox.core.clientsClaim()

构建工具配置

一些可传递到 workbox-cli、workbox-build 或 workbox-webpack-plugin 的选项的命名发生了变化。每当选项名称中使用“Url”时,它将被弃用,取而代之的是“网址”。这意味着,最好使用以下选项名称:

  • dontCacheBustURLsMatching
  • ignoreURLParametersMatching
  • modifyURLPrefix
  • templatedURLs

这些选项名称的“Url”变体在 v4 中仍然有效,但会导致一条警告消息。我们建议开发者在 v5 版本发布之前进行迁移。

新功能

工作框窗口

新的 workbox-window 模块简化了 Service Worker 注册和检测更新的过程,并在 Service Worker 中运行的代码与 Web 应用的 window 上下文中运行的代码之间提供了标准通信方式。

虽然使用 workbox-window 是可选的,但我们希望开发者能够使用它,并考虑迁移一些手写逻辑,以便在适当情况下使用。如需详细了解如何使用 workbox-window,请参阅模块指南

迁移示例

如需查看从 Workbox v3 到 v4 的实际迁移示例,请参阅此拉取请求

获取帮助

我们预计大多数迁移都比较简单。如果您遇到本指南未涵盖的问题,请在 GitHub 上提交问题告诉我们。