使用GenerateSW和Workbox缓存外部JavaScript文件的配置问题
Workbox GenerateSW 后缀匹配缓存外部JS失效解决方案
问题根因
- 核心原因是Workbox的
runtimeCaching对正则匹配的默认逻辑:如果正则表达式未以^http开头,Workbox会将其识别为同域路径匹配规则,不会应用到跨域的第三方资源请求上,因此仅匹配.js后缀的规则只会对项目自身的同域JS生效,跨域CDN的外部JS无法命中规则。 - 次要场景:如果外部JS的URL携带查询参数(如
xxx.js?v=hash),/\.(?:js)$/的正则仅匹配URL末尾为.js的情况,带参数的请求也会匹配失败。
解决方案
方案1:匹配所有同域+跨域的JS资源
如果需要统一缓存所有.js后缀的资源,修改正则规则兼容跨域和查询参数即可:
const WorkboxPlugin = require('workbox-webpack-plugin') configureWebpack: { plugins: [ new WorkboxPlugin.GenerateSW({ runtimeCaching: [ { handler: 'StaleWhileRevalidate', method: 'GET', urlPattern: new RegExp('^https?://.*\\.js(\\?.*)?$'), options: { cacheName: 'javascript', // 可选:配置缓存过期策略 expiration: { maxEntries: 50, maxAgeSeconds: 30 * 24 * 60 * 60 // 缓存30天 }, // 可选:仅缓存响应正常的请求 cacheableResponse: { statuses: [200] } } } ] }) ] }
注意:该方案会匹配所有第三方域名的JS资源,可能会缓存不需要的动态第三方脚本(如统计、广告类JS)引发业务异常,生产环境不推荐使用。
方案2:拆分同域/指定跨域域名的缓存规则
更安全的做法是分别配置同域JS和确定需要缓存的第三方域名JS的规则:
runtimeCaching: [ // 同域JS缓存规则 { handler: 'StaleWhileRevalidate', method: 'GET', urlPattern: /\.(?:js)$/, options: { cacheName: 'local-javascript' } }, // 第三方指定域名JS缓存规则 { handler: 'StaleWhileRevalidate', method: 'GET', urlPattern: /^https:\/\/code\.iconify\.design/, options: { cacheName: 'external-javascript', expiration: { maxEntries: 10, maxAgeSeconds: 60 * 24 * 60 * 60 }, cacheableResponse: { statuses: [200] } } } ]
修改配置后需要重新构建项目,并清除浏览器旧的Service Worker缓存即可生效。
内容的提问来源于stack exchange,提问作者Mike Mitterer
相关产品推荐
相关产品推荐

