/* eslint-env worker */ /* global FetchEvent */ import 'whatwg-fetch'; import WorkboxSW from 'workbox-sw'; import parseQs from 'yoho-qs/parse'; /** * 需要缓存的路径 */ const CACHED_PATH = [ 'boys', 'girls', 'kids', 'lifestyle', 'cate', 'list', 'search', 'product', 'shop', 'guang' ]; const config = { customCacheUrl: [ /^https:\/\/(.*)cdn\.yoho\.cn/i // /^https:\/\/(.*)static\.yhbimg\.com/i ], precachePage: [ '/offline.html' ], precacheStaticFile: [ '/index.css', '/common.css', '/libs.js', '/font/iconfont.woff', '/common.offline.js', '/common.offline.css' ], precacheCdnStaticFile: [ 'https://cdn.yoho.cn/pwa/404.png' ] }; const qs = parseQs(self.location.search.substr(1)); const workboxSW = new WorkboxSW({ clientsClaim: true, skipWaiting: true }); const cacheFirstStrategy = workboxSW.strategies.cacheFirst({ cacheableResponse: { statuses: [0, 200] }, cacheExpiration: { maxEntries: 1000, maxAgeSeconds: 7 * 24 * 60 * 60 // 7 day } }); // 特殊路径的预缓存文件文件 const precacheFile = [{ url: '/sw.js?t=' + qs.t + '&staticServer=' + qs.staticServer }].concat(config.precacheStaticFile.map(file => { // 根据业务自定义资源路径 const url = self.location.protocol + qs.staticServer + file + '?t=' + qs.t; return { url: url }; })).concat(config.precachePage.map(page => { return { url: page + '?t=' + qs.t }; })).concat(config.precacheCdnStaticFile.map(file => { return { url: file }; })); // 预加载文件 workboxSW.precache(precacheFile); // 自定义缓存 config.customCacheUrl.forEach(urlRegExp => { workboxSW.router.registerRoute( urlRegExp, cacheFirstStrategy ); }); // 所有网络走 worker,异常时增加离线页面 workboxSW.router.registerRoute(args => { let cached = false; let routeRegExp = new RegExp(`^\/(${CACHED_PATH.join('|')})`); if (/^https:\/\/m.yohobuy.com/.test(args.url.href) && (routeRegExp.test(args.url.pathname) || args.url.pathname === '/')) { cached = true; } if (args.event.request.headers.get('x-requested-with') === 'XMLHttpRequest') { cached = false; } return cached; }, args => { return workboxSW.strategies.networkFirst({ cacheExpiration: { maxEntries: 300, maxAgeSeconds: 12 * 60 * 60 // 12 小时 } }).handle(args).then(res => { if (res || args.event.request.mode !== 'navigate') { return res; } // navigate 请求失败后,返回网络异常页面 return caches.match('offline.html?t=' + qs.t); }); }); /** * webp 处理 * 匹配非 webp 的 cdn 图片资源,缓存其 webp 格式 */ workboxSW.router.registerRoute(args => { let useWebp = false; let supportWebp = /image\/webp/i.test(args.event.request.headers.get('Accept')); if (!supportWebp) { return useWebp; } if (/^https:\/\/(.*)static\.yhbimg\.com(.*)(png|jpg|jpeg)\?(imageView|imageMogr)(.*)/.test(args.url.href) && /^(?!.*format\/).*/.test(args.url.href)) { useWebp = true; } return useWebp; }, args => { // 重新构造 fetch 请求 args.event = new FetchEvent(args.event.type, { request: new Request(args.event.request.url + '/format/webp'), clientId: args.event.clientId, isReload: args.event.isReload }); return workboxSW.strategies.networkOnly().handle(args); });