高级 (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
,你必须使用以下方式配置它:
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'
VitePWA({
strategies: 'injectManifest',
});
开发
如果您希望 service worker 在开发环境中运行,请确保在 devOptions 中启用它,并在需要时将 type 设置为 module
Service Worker 代码
自定义 service worker ( public/sw.js
)至少应该有以下代码(你还需要将 workbox-precaching
作为 dev dependency
安装到你的项目中):
import { precacheAndRoute } from 'workbox-precaching';
precacheAndRoute(self.__WB_MANIFEST);
如果你没有使用 precaching
( self.__WB_MANIFEST
),你需要禁用 injection point
以避免编译错误(仅从版本 ^0.14.0
开始),将以下选项添加到你的 pwa 配置中:
injectManifest: {
injectionPoint: undefined;
}
Service worker 浏览器中的错误
查看新的 Vite 构建部分获取更多详细信息,以下描述的错误已在 v0.18.0+
中修复,并且不需要使用 iife
格式来构建您的 service worker。
如果您的 service worker 代码使用意外的 exports
编译(例如: export default require_sw();
),您可以将构建输出格式更改为 iife
,将以下代码添加到您的 pwa 配置:
injectManifest: {
rollupFormat: 'iife';
}
清理过期缓存
service worker 会把你所有的应用资源存储在浏览器缓存(或一组缓存)中。每次你对应用进行修改并重新构建时,service worker 也会被重新构建,包括在它的预缓存清单中所有新修改的资产,这些资产的版本也会发生变化(所有被修改的资产都会有一个新版本)。没有被修改过的资产也会被包含在 service worker 的预缓存清单中,但它们的修订版本不会改变。
预缓存清单条目修改
预缓存清单条目的修订只是资产内容的哈希 MD5
,如果资产没有被修改,那么计算出来的哈希将始终相同
当用户安装应用程序的新版本时,我们会在 service worker 缓存中缓存所有新资产以及旧资产。要删除旧资产(来自不再需要的先前版本),由于您正在构建自己的 service worker,因此需要在自定义 service worker 中添加以下代码
import { cleanupOutdatedCaches, precacheAndRoute } from 'workbox-precaching';
cleanupOutdatedCaches();
precacheAndRoute(self.__WB_MANIFEST);
我们强烈建议您在自定义 Service Worker 中包含以上代码
Inject Manifest Source Map 新选项自 v0.18.0+
信息
从 v0.18.0+
开始,你可以在 injectManifest
配置选项中使用 minify
、sourcemap
和enableWorkboxModulesLogs
,查看 New Vite Build 部分了解更多详情。
由于您正在构建自己的 service worker,这个插件将使用 Vite 的 build.sourcemap
配置选项,默认值为 false
来生成源码映射
如果您想为 service worker 生成源码映射,则需要为整个应用程序生成源码映射
自定义 Rollup 和 Vite 插件从 v0.18.0+
从 v0.18.0
,您可以在新的 buildPlugins
选项中使用 rollup
和 vite
添加自定义 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'
:
VitePWA({
registerType: 'autoUpdate',
});
Service Worker 代码
您必须在您的 service worker 代码中至少包含以下代码(您还需要将workbox-core
安装为 dev dependency
到您的项目中)
import { clientsClaim } from 'workbox-core';
self.skipWaiting();
clientsClaim();
更新提示行为
如果你需要自定义 service worker 与 Prompt For Update
行为一起工作,你需要更改你的 service worker 代码
Service Worker 代码
你至少需要在 service worker 中包含以下代码:
self.addEventListener('message', (event) => {
if (event.data && event.data.type === 'SKIP_WAITING') self.skipWaiting();
});
TypeScript 支持
你可以使用 TypeScript 编写自定义 service worker。要解析 service worker 类型,只需在 tsconfig.json
文件中添加 WebWorker
到 lib
条目中:
{
"compilerOptions": {
"lib": ["ESNext", "DOM", "WebWorker"]
}
}
插件配置
我们建议您将自定义 service worker 放在 src
目录中。
你需要在你的 vite.config.ts
文件中配置 srcDir: 'src'
和 filename: 'sw.ts'
插件选项,正确配置这两个选项的目录和自定义 service worker 的名称·
VitePWA({
srcDir: 'src',
filename: 'sw.ts',
});
Service Worker Code
你需要用 ServiceWorkerGlobalScope
定义 self
作用域:
import { precacheAndRoute } from 'workbox-precaching';
declare let self: ServiceWorkerGlobalScope;
precacheAndRoute(self.__WB_MANIFEST);