sw.js 3.95 KB
importScripts("https://cdn.yoho.cn/workbox/workbox-sw.js", "https://cdn.yoho.cn/workbox/workbox-core.prod.js", "https://cdn.yoho.cn/workbox/workbox-precaching.prod.js", "https://cdn.yoho.cn/workbox/workbox-routing.prod.js", "https://cdn.yoho.cn/workbox/workbox-cache-expiration.prod.js", "https://cdn.yoho.cn/workbox/workbox-strategies.prod.js", "//cdn.yoho.cn/yohobuywap-node/precache-manifest.5892d915861d21c8df45a91e2d832243.js");

/* eslint-env worker */
/* global FetchEvent */
self.workbox.skipWaiting();
self.workbox.clientsClaim();

const isDev = self.location.search.indexOf('dev') >= 0;
const staticDomian = isDev ? /^http:\/\/localhost:5001/i : /^https:\/\/(.*)cdn\.yoho\.cn/i;
const webDomian = isDev ? /^http:\/\/localhost:6001/i : /^https:\/\/m.yohobuy.com/;

// 定义缓存前缀
const NAME_CACHE_PREFIX = 'yoho-cache';

const precaches = [
    {
        url: '/offline.html',
        revision: 'offline-revision-0.0.2'
    },
    {
        url: '//cdn.yoho.cn/pwa/404.png',
        revision: '404-revision-0.0.1'
    }].concat(self.__precacheManifest || []);

self.workbox.precaching.precacheAndRoute(precaches);

/**
 * 需要缓存的路径
 */
// const CACHED_PATH = [
//     'boys',
//     'girls',
//     'kids',
//     'lifestyle',
//     'cate',
//     'list',
//     'search',
//     'product',
//     'shop',
//     'guang',
//     'offline.html'
// ];

// let routeRegExp = new RegExp(`^\/(${CACHED_PATH.join('|')})`);

// 自定义缓存
self.workbox.routing.registerRoute(args => {
    if (/sockjs-node\/info/.test(args.url.href)) {
        return false;
    }
    if (self.__precacheManifest.find(precahce => args.url.href.indexOf(precahce.url) >= 0)) {
        return false;
    }
    if (staticDomian.test(args.url.href)) {
        return true;
    }
    return false;
}, self.workbox.strategies.staleWhileRevalidate({
    cacheName: `${NAME_CACHE_PREFIX}-statics`,
    plugins: [
        new self.workbox.expiration.Plugin({
            maxEntries: 1000,
            maxAgeSeconds: 7 * 24 * 60 * 60 // 7 day
        })
    ]
}));

// 所有网络走 worker,异常时增加离线页面
self.workbox.routing.registerRoute(args => {
    let cached = webDomian.test(args.url.href);

    if (args.event.request.headers.get('x-requested-with') === 'XMLHttpRequest' &&
        args.event.request.method !== 'GET') {
        cached = false;
    }

    return cached;
}, args => {
    return self.workbox.strategies.networkFirst({
        cacheName: `${NAME_CACHE_PREFIX}-runtime`,
        plugins: [
            new self.workbox.expiration.Plugin({
                maxEntries: 300,
                maxAgeSeconds: 12 * 60 * 60 // 12 小时
            })
        ]
    }).handle(args).then(res => {
        if (res || args.event.request.mode !== 'navigate') {

            // TODO report
            return res;
        }

        // navigate 请求失败后,返回网络异常页面
        return caches.match('offline.html');
    });
});

/**
 * webp 处理
 * 匹配非 webp 的 cdn 图片资源,缓存其 webp 格式
 */
self.workbox.routing.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 self.workbox.strategies.staleWhileRevalidate({
        cacheName: `${NAME_CACHE_PREFIX}-images`,
        plugins: [
            new self.workbox.expiration.Plugin({
                maxEntries: 100,
                maxAgeSeconds: 24 * 60 * 60 // 24 小时
            })
        ]}).handle(args);
});