Workbox 的方式

Workbox 非常灵活,几乎可以适应任何项目的构建流程。这意味着您可以通过多种方式使用 Workbox,您可以为自己的项目选择合适的集成。无论您采用何种方式与 Workbox 集成,各种工具都会提供类似的 API。

generateSWinjectManifest

您将依赖 Workbox 构建工具的两个核心方法之一:generateSWinjectManifest。您应该使用哪一个取决于您需要多大的灵活性。generateSW 注重易用性和简单性,但以灵活性为代价,允许您声明一组配置选项,并为您提供功能齐全的 Service Worker。

injectManifest 支持更高的灵活性,但代价是简单性,因为您最终需要自行为 Service Worker 编写代码,而 injectManifest 会提供预缓存清单,可供 Workbox 的预缓存方法使用。

何时使用 generateSW

在以下情况下,您应使用 generateSW

  • 您需要预缓存与构建流程关联的文件,包括网址中包含您可能提前不知道的哈希的文件。
  • 您有简单的运行时缓存需求,可以通过 generateSW 的选项进行配置。

哪些情况下不应使用 generateSW

另一方面,在以下情况下,不应使用 generateSW

  • 您想使用其他 Service Worker 功能(例如 Web 推送)。
  • 您需要更高的灵活性来导入其他脚本,或使用特定的 Workbox 模块根据应用的需求微调 Service Worker。

何时使用 injectManifest

在以下情况下,您应使用 injectManifest

  • 您希望预缓存文件,但希望编写自己的 Service Worker。
  • 您有复杂的缓存或路由需求,无法通过 generateSW 的配置选项表示
  • 您希望在 Service Worker 中使用其他 API(例如 Web Push)。

injectManifestgenerateSW 的不同之处在于,它要求您指定源 Service Worker 文件。在此工作流中,源 Service Worker 文件必须包含特殊的 self.__WB_MANIFEST 字符串,以便 injectManifest 可以将其替换为预缓存清单

哪些情况下不应使用 injectManifest

在以下情况下,不应使用 injectManifest

  • 您不想在 Service Worker 中使用预缓存。
  • 我们的 Service Worker 要求非常简单,通过 generateSW 及其配置选项就能做到这一点。
  • 您优先考虑易用性而非灵活性。

使用 Workbox 的构建工具

如果您正在寻找一种不依赖于框架的方式在构建流程中使用 Workbox,有以下三种选择:

  1. workbox-cli
  2. workbox-build。命令行工具。
  3. 使用捆绑器(例如 workbox-webpack-plugin)。

每个构建工具均提供 generateSWinjectManifest 模式,以及一组类似的选项。当您不想将由 Workbox 提供支持的 Service Worker 与特定框架绑定时,这些都是不错的选择。为了解哪个选项最适合,我们来快速了解一下每个选项。

workbox-cli

如果您正在寻找使用 Workbox 进入门槛最低的门槛,那么 CLI 适合您:

npm install workbox-cli --save-dev

如需开始使用 CLI,请使用 npx workbox wizard 运行向导。该向导会询问几个问题,我们将根据您对这些问题的回答来设置项目,并包含 workbox-config.js 文件,您可以根据需要自定义该文件。代码大致如下所示:

// A config for `generateSW`
export default {
  globDirectory: 'dist/',
  globPatterns: [
    '**/*.{css,woff2,png,svg,jpg,js}'
  ],
  swDest: 'dist/sw.js'
};

创建配置文件后,CLI 可以为您运行 generateSWinjectManifest 方法。CLI 的帮助文本包含更多信息和用法示例。

workbox-build

workbox-cliworkbox-build 模块的封装容器,替代方案是直接使用 workbox-build。使用 workbox-build 时,您应直接将 generateSWinjectManifest 方法作为 Node 脚本的一部分使用,并传入一组类似的选项,而不是使用 workbox-config.js 文件指定选项:

// build-sw.mjs
import {generateSW} from 'workbox-build';

generateSW({
  globDirectory: 'dist/',
  globPatterns: [
    '**/*.{css,woff2,png,svg,jpg,js}'
  ],
  swDest: 'dist/sw.js'
});

在上述示例中,运行 node build-sw.mjs 命令时,workbox-build 会将生成的 Service Worker 写入 dist 目录。

使用捆绑器

各种捆绑器都有自己的 Workbox 插件,但 Workbox 团队正式支持的唯一捆绑器是通过 workbox-webpack-plugin 的 webpack。与 workbox-cliworkbox-build 一样,workbox-webpack-plugin 将运行 generateSWinjectManifest 方法,但插件会将这些方法名称首字母大写为 GenerateSWInjectManifest。除此之外,用法与 workbox-build 类似:

// webpack.config.js
import {GenerateSW} from 'workbox-webpack-plugin';

export default {
  // Other webpack config options omitted for brevity...
  plugins: [
    new GenerateSW({
      swDest: './dist/sw.js'
    })
  ]
};

您传递给 GenerateSWInjectManifest 的选项与 generateSWinjectManifest 不同,但它们之间存在明显的重叠。特别是,您无需(也不能)为 GenerateSW 指定 globDirectory 选项,因为 webpack 已经知道正式版资源的捆绑位置。

使用框架

本文介绍的所有内容都侧重于使用 Workbox,无论用户的框架偏好设置如何。不过,如果 Workbox 让开发变得更简单,您也可以在特定框架中使用 Workbox。例如,create-react-app 默认附带 Workbox后续文章中介绍了与 Workbox 的不同框架集成。

值得注意的是,这些针对特定框架的 Workbox 集成可能会限制您以自己想要的方式配置 Workbox 的能力。在此类情况下,您随时可以回退到此处讨论的方法。

如果没有构建流程该怎么办?

本文档假定您的项目有构建流程,但项目实际上可能没有构建流程。如果您的情况符合上述情况,仍然可以将 Workbox 与 workbox-sw 模块搭配使用。借助 workbox-sw,您可以从 CDN 或本地加载 Workbox 运行时,并编写您自己的 Service Worker。

总结

Workbox 的灵活性确保您可以在几乎任何项目中使用它,无论其框架或工具链偏好设置如何。所有这些方法都可让您使用几种方法完成预缓存和运行时缓存,同时可以在需要时更灵活地构建具有更高级功能的 Service Worker。