Skip to content

高级 (injectManifest)

使用 service worker 策略 ,你可以构建自己的 service worker

vite-plugin-pwa 插件将编译你的自定义 service worker 并注入 service worker 的预缓存清单

默认情况下,插件将假定 service worker 源代码位于 Vite的public 文件夹,名为 sw.js ,也就是说,它将在以下文件中搜索: /public/sw.js

如果要更改位置或 service worker 名称,则需要更改以下插件选项:

  • srcDir: 必须是相对于项目根目录的
  • filename: 包括文件扩展名,必须相对于 srcDir 文件夹

例如,如果你的 service worker 位于 /src/my-sw.js ,你必须使用以下方式配置它:

ts
import { VitePWA } from 'vite-plugin-pwa';

export default defineConfig({
  plugins: [
    VitePWA({
      strategies: 'injectManifest',
      srcDir: 'src',
      filename: 'my-sw.js',
    }),
  ],
});

自定义 Service worker

我们建议您使用 Workbox 来构建您的 service worker,而不是使用 importScripts ,您需要包含 workbox-* 依赖项作为 dev dependencies 到您的项目中。

插件配置

在您的 vite.config.ts ,vite-plugin-pwa 插件选项中,您必须配置 strategies: 'injectManifest'

ts
VitePWA({
  strategies: 'injectManifest',
});

开发

如果您希望 service worker 在开发环境中运行,请确保在 devOptions 中启用它,并在需要时将 type 设置为 module

Service Worker 代码

自定义 service worker ( public/sw.js )至少应该有以下代码(你还需要将 workbox-precaching 作为 dev dependency 安装到你的项目中):

js
import { precacheAndRoute } from 'workbox-precaching';

precacheAndRoute(self.__WB_MANIFEST);

如果你没有使用 precaching ( self.__WB_MANIFEST ),你需要禁用 injection point 以避免编译错误(仅从版本 ^0.14.0 开始),将以下选项添加到你的 pwa 配置中:

ts
injectManifest: {
  injectionPoint: undefined;
}

Service worker 浏览器中的错误

查看新的 Vite 构建部分获取更多详细信息,以下描述的错误已在 v0.18.0+ 中修复,并且不需要使用 iife 格式来构建您的 service worker。

如果您的 service worker 代码使用意外的 exports 编译(例如: export default require_sw(); ),您可以将构建输出格式更改为 iife ,将以下代码添加到您的 pwa 配置:

ts
injectManifest: {
  rollupFormat: 'iife';
}

清理过期缓存

service worker 会把你所有的应用资源存储在浏览器缓存(或一组缓存)中。每次你对应用进行修改并重新构建时,service worker 也会被重新构建,包括在它的预缓存清单中所有新修改的资产,这些资产的版本也会发生变化(所有被修改的资产都会有一个新版本)。没有被修改过的资产也会被包含在 service worker 的预缓存清单中,但它们的修订版本不会改变。

预缓存清单条目修改

预缓存清单条目的修订只是资产内容的哈希 MD5 ,如果资产没有被修改,那么计算出来的哈希将始终相同

当用户安装应用程序的新版本时,我们会在 service worker 缓存中缓存所有新资产以及旧资产。要删除旧资产(来自不再需要的先前版本),由于您正在构建自己的 service worker,因此需要在自定义 service worker 中添加以下代码

js
import { cleanupOutdatedCaches, precacheAndRoute } from 'workbox-precaching';

cleanupOutdatedCaches();

precacheAndRoute(self.__WB_MANIFEST);

我们强烈建议您在自定义 Service Worker 中包含以上代码

Inject Manifest Source Map 新选项自 v0.18.0+

信息

v0.18.0+开始,你可以在 injectManifest 配置选项中使用 minifysourcemapenableWorkboxModulesLogs,查看 New Vite Build 部分了解更多详情。

由于您正在构建自己的 service worker,这个插件将使用 Vite 的 build.sourcemap 配置选项,默认值为 false 来生成源码映射

如果您想为 service worker 生成源码映射,则需要为整个应用程序生成源码映射

自定义 Rollup 和 Vite 插件从 v0.18.0+

v0.18.0 ,您可以在新的 buildPlugins 选项中使用 rollupvite 添加自定义 Rollup 和 Vite 插件来构建 service worker。

警告

旧的 plugins 已被弃用,使用 buildPlugins.rollup 代替:

  • 如果配置了 buildPlugins.rollup ,则忽略 plugins
  • 如果没有配置 buildPlugins.rollup ,则使用 plugins

你可以查看vue-router example使用一个自定义 Vite 插件,该插件使用简单的虚拟模块都是由 service workers 消费。

自动更新行为

如果您需要自定义 service worker 与 Auto Update 行为一起工作,则需要更改插件配置选项并向 service worker 代码中添加一些自定义代码

插件配置

您必须在您的 vite.config.ts 文件中为vite-plugin-pwa 插件选项配置registerType: 'autoUpdate' :

ts
VitePWA({
  registerType: 'autoUpdate',
});

Service Worker 代码

必须在您的 service worker 代码中至少包含以下代码(您还需要将workbox-core 安装为 dev dependency 到您的项目中)

js
import { clientsClaim } from 'workbox-core';

self.skipWaiting();
clientsClaim();

更新提示行为

如果你需要自定义 service worker 与 Prompt For Update 行为一起工作,你需要更改你的 service worker 代码

Service Worker 代码

你至少需要在 service worker 中包含以下代码:

js
self.addEventListener('message', (event) => {
  if (event.data && event.data.type === 'SKIP_WAITING') self.skipWaiting();
});

TypeScript 支持

你可以使用 TypeScript 编写自定义 service worker。要解析 service worker 类型,只需在 tsconfig.json 文件中添加 WebWorkerlib 条目中:

json
{
  "compilerOptions": {
    "lib": ["ESNext", "DOM", "WebWorker"]
  }
}

插件配置

我们建议您将自定义 service worker 放在 src 目录中。

你需要在你的 vite.config.ts 文件中配置 srcDir: 'src'filename: 'sw.ts' 插件选项,正确配置这两个选项的目录和自定义 service worker 的名称·

ts
VitePWA({
  srcDir: 'src',
  filename: 'sw.ts',
});

Service Worker Code

你需要用 ServiceWorkerGlobalScope 定义 self 作用域:

ts
import { precacheAndRoute } from 'workbox-precaching';

declare let self: ServiceWorkerGlobalScope;

precacheAndRoute(self.__WB_MANIFEST);

在MIT许可下发布.