Nuxt3 通过 @vite-pwa/nuxt 模块集成 PWA 能力,但实际配置中常遇到 Service Worker 未注册、缓存不完整、更新不生效等问题。本文记录完整的排查清单与 Workbox 缓存优化方案。
| 问题 | 原因 | 解决方案 |
|---|---|---|
| SW 未注册 | 缺少 VitePwaManifest 组件 | app.vue 中添加组件 |
| 缓存文件不全 | globPatterns 未覆盖文件类型 | 扩展缓存类型列表 |
| SW activated 始终 false | 更新周期未配置 | 设置 periodicSyncForUpdates |
| 离线无法访问 | 缓存范围太小 | 扩大 globPatterns |
pnpm add -D @vite-pwa/nuxt// nuxt.config.ts
export default defineNuxtConfig({
modules: ['@vite-pwa/nuxt'],
pwa: {
registerType: 'autoUpdate',
manifest: {
name: 'My Nuxt PWA',
short_name: 'NuxtPWA',
theme_color: '#ffffff',
icons: [
{ src: '/pwa-192x192.png', sizes: '192x192', type: 'image/png' },
{ src: '/pwa-512x512.png', sizes: '512x512', type: 'image/png' },
],
},
},
})<!-- app.vue -->
<template>
<div>
<NuxtPage />
<!-- 必须:注入 PWA manifest 链接 -->
<VitePwaManifest />
</div>
</template>缺少 <VitePwaManifest /> 是 SW 未注册的最常见原因。
默认 globPatterns 只缓存 js/css/html,图片和字体会缺失:
// nuxt.config.ts
export default defineNuxtConfig({
pwa: {
workbox: {
globPatterns: [
// 核心资源
'**/*.{js,css,html}',
// 图片资源
'**/*.{png,jpg,jpeg,svg,gif,webp,ico,avif}',
// 字体资源
'**/*.{woff,woff2,ttf,eot,otf}',
// 数据资源
'**/*.{json,xml}',
],
},
},
})pwa: {
workbox: {
globPatterns: ['**/*.*'],
},
}| 风险 | 说明 |
|---|---|
| 大文件缓存 | 视频/音频文件撑爆缓存配额 |
| 安装缓慢 | 首次缓存大量文件耗时长 |
| 配额超限 | 浏览器存储配额有限(通常 50MB-2GB) |
大型项目应精确配置类型,排除大体积资源。
pwa: {
workbox: {
runtimeCaching: [
{
urlPattern: /^https:\/\/api\.example\.com\/.*/i,
handler: 'NetworkFirst',
options: {
cacheName: 'api-cache',
expiration: { maxEntries: 50, maxAgeSeconds: 300 },
},
},
{
urlPattern: /\.(?:png|jpg|jpeg|svg|gif|webp)$/,
handler: 'CacheFirst',
options: {
cacheName: 'image-cache',
expiration: { maxEntries: 100, maxAgeSeconds: 60 * 60 * 24 * 30 },
},
},
],
},
}pwa: {
devOptions: {
enabled: true, // 开发环境也启用 SW(调试用)
},
workbox: {
// 每 60 秒检查一次 SW 更新
periodicSyncForUpdates: 60,
},
}不配置此项时,SW 更新检查依赖浏览器默认策略(通常 24 小时),导致新版本长时间不生效。
registerType: 'autoUpdate' 配合 periodicSyncForUpdates 实现静默更新。
遇到问题时按顺序检查:
app.vue 是否包含 <VitePwaManifest />nuxt.config.ts 中 pwa 模块是否正确注册.output/public)中是否存在 sw.jsQ: 开发环境需要启用 PWA 吗?
默认不启用(避免 SW 缓存干扰 HMR)。调试 PWA 时设置 devOptions.enabled: true,注意开发环境的 SW 可能缓存旧资源,需手动 Unregister 后刷新。
Q: iOS Safari 对 PWA 支持如何?
iOS 16.4+ 支持 Web Push,但后台同步(Background Sync)支持有限。iOS 上 PWA 需通过"添加到主屏幕"安装,缓存策略受 ITP 影响可能更激进地清理。
Q: 如何强制用户更新到新版本?
registerType: 'prompt' 模式下可监听更新事件,弹出提示让用户手动刷新:
// plugins/pwa-update.client.ts
export default defineNuxtPlugin(() => {
const pwa = useRegisterSW()
// 监听新 SW 就绪,提示用户刷新
})