workbox预缓存需构建时生成资源清单并由generatesw插件注入,install阶段原子写入失败(如404、跨域)会导致sw卡在waiting状态,且activate阶段须显式清理旧缓存以防泄漏。

Workbox 的预缓存不是“配个配置就自动生效”,它依赖构建时生成的资源清单 + 运行时 install 阶段的原子写入,任一路径 404 或跨域失败,整个 SW 安装就会卡在 waiting 状态——这是最常导致“明明注册了 SW 却没离线效果”的根本原因。
precacheAndRoute(self.__WB_MANIFEST) 为什么必须配合 GenerateSW 插件
precacheAndRoute 不是万能胶水,它只负责把 self.__WB_MANIFEST 里的条目塞进缓存,但这个变量本身得由构建工具注入。如果你手写 sw.js 并直接调用 precacheAndRoute,self.__WB_MANIFEST 就是 undefined,运行时会报 Cannot read property 'map' of undefined。
必须用 workbox-webpack-plugin.GenerateSW(或 workbox-cli 的 generateSW 模式)才能自动生成带 manifest 的完整 sw.js。常见错误包括:
- 误用
InjectManifest模式却没手动插入self.__WB_MANIFEST - Webpack 输出目录和
swDest路径不一致,导致页面注册的/service-worker.js实际 404 - 没设
importWorkboxFrom: 'local',国内环境加载 CDN 上的 Workbox 库超时,install 阶段直接 reject
cache.addAll() 失败的典型表现和定位方法
Chrome DevTools 的 Application → Service Workers 面板里,如果看到新 SW 长期停留在 waiting 状态,且控制台没报错,大概率是 cache.addAll() 在 install 中静默失败了。
验证方式很简单:打开 Network 面板,勾选 “Preserve log”,刷新页面,看 install 阶段发起的那些预缓存 URL 是否有 404、500 或 CORS 错误。特别注意以下几类路径:
-
'/'—— 它必须返回index.html,不能是 Web 服务器默认的目录列表页 -
/assets/logo.123abc.png—— 构建后文件名带哈希,但 SW 脚本没更新,旧 manifest 里还是老哈希值 -
/api/config.json—— 预缓存不该包含动态接口,这类请求应走 runtime cache -
https://fonts.googleapis.com/css—— 跨域资源没配 CORS,浏览器直接拦截
预缓存清单里 revision 字段到底起什么作用
revision 不是版本号,它是 Workbox 判断资源是否变更的唯一依据。只要两个 URL 的 url 相同但 revision 不同,Workbox 就认为这是新资源,安装时会覆盖旧缓存;如果 url 相同、revision 也相同,就跳过写入。
所以你不需要、也不应该手写 revision。Webpack 插件会自动从文件内容计算 hash 填进去,例如:
[
{ url: "main.css", revision: "a1b2c3d4" },
{ url: "app.js", revision: "e5f6g7h8" }
]
一旦你手动改了 revision,或者构建产物没变但插件误生成了新 hash,就可能引发缓存不一致。真正要盯的是构建流程是否稳定输出可复现的 hash 值。
activate 阶段不清理旧缓存,会导致磁盘空间泄漏
每次改 CACHE_NAME 或升级 Workbox 版本,都会生成一个新缓存空间(比如 my-app-precache-v2),但旧缓存(如 v1)不会自动消失。它们堆在 caches.keys() 里,既占空间,又可能被 runtime cache 错误命中。
必须在 SW 的 activate 事件中显式清理:
self.addEventListener('activate', (event) => {
event.waitUntil(
caches.keys().then(keys =>
Promise.all(
keys
.filter(key => key !== CACHE_NAME)
.map(key => caches.delete(key))
)
)
);
});
注意:activate 只有在旧 SW 不再控制任何页面时才触发。开发时可手动点击 Application → Cache Storage 里的旧缓存名,点右上角“Delete”快速清空,比等自动清理更可靠。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











