sw.js
3.52 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* 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
};
})).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 === '/') ||
args.event.request.headers.get('x-requested-with') !== 'XMLHttpRequest') {
cached = true;
}
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');
});
});
/**
* 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);
});