预缓存清单路径错误:使用Workbox.injectManifest生成Service Worker遇问题
解决Workbox.injectManifest预缓存清单路径错误问题
看起来你在配置Workbox和Webpack结合时,因为路径基准没对齐导致了预缓存清单的路径问题,我帮你梳理下问题根源和解决方案:
首先,先明确几个关键配置的作用:
- Webpack的
output.path是path.resolve("./scripts/app/dist"),意味着所有打包产物都会输出到这个目录下 - Workbox的
swDest: "../../../sw.js"是相对于Webpack输出目录的路径,所以最终生成的sw.js会放在项目根目录(从scripts/app/dist往上退三级就是根目录) - 而你设置的
globDirectory: path.resolve("./")是Workbox查找文件的基准目录,也就是项目根目录,这时候Workbox会从根目录开始匹配globPatterns里的规则,但这里有个隐患:你可能把未打包的源码(比如scripts/app/src下的文件)也加入了预缓存清单,而不是打包后的产物。
具体修复方案
1. 精准匹配打包后的资源,排除源码
修改Workbox配置,只针对打包后的文件生成预缓存清单,同时排除不必要的文件:
new WorkboxPlugin.InjectManifest({ swSrc: path.resolve("./scripts/app/src/service-worker.js"), swDest: "../../../sw.js", globDirectory: path.resolve("./"), globPatterns: [ // 只匹配dist目录下的打包产物,而不是整个scripts目录 "scripts/app/dist/**/*.js", "fonts/**/*.{eot,ttf,woff,woff2,otf}" ], globIgnores: [ "scripts/app/src/**/*", // 忽略源码目录,避免缓存未打包文件 "**/*.map" // 可选:忽略sourcemap文件,减少缓存体积 ], // 调整预缓存路径的前缀,确保和Service Worker的位置匹配 modifyURLPrefix: { // 如果你的sw在根目录,访问打包后的JS需要走/scripts/app/dist/xxx.js,这个配置可以保留; // 如果你的服务器把dist目录设为静态资源根,可以改成"scripts/app/dist/": "/" "scripts/app/dist/": "" } })
2. 确认Service Worker中的预缓存逻辑正确
在你的service-worker.js源文件中,要正确使用Workbox提供的预缓存方法:
import { precacheAndRoute } from 'workbox-precaching'; // Workbox会自动把预缓存清单注入到self.__WB_MANIFEST中 precacheAndRoute(self.__WB_MANIFEST);
3. 验证最终生成的清单路径
打包完成后,打开项目根目录下的sw.js,查看self.__WB_MANIFEST数组里的url值,确保这些路径在浏览器中能正常访问(比如直接在地址栏输入路径,看是否能加载到对应资源)。
额外提醒
- 不要混淆路径基准:
swDest的相对基准是Webpack的output.path,而globDirectory是Workbox扫描文件的基准,两者的相对关系一定要理清楚 - 如果你的部署环境是把
scripts/app/dist作为网站的根目录,那可以简化配置:把globDirectory设为path.resolve("./scripts/app/dist"),swDest设为sw.js,这样生成的sw.js会在dist目录下,预缓存路径也会自动匹配相对路径,更不容易出错
内容的提问来源于stack exchange,提问作者Mario Lopez
相关产品推荐
相关产品推荐

