文档见官网
我们不用配置就可以跑起来,但是配置里面有些地方需要注意的而且不能乱改,自行看文档。配置常用的是:caches(默认全部缓存,也可以自己设置),externals(数组形式,表示其他资源如cdn),excludes(数组形式,除了哪些不能被缓存),autoUpdate(多久后更新,默认一小时)
我们使用offline-plugin这个插件,只需要在插件里面直接引入即可:
plugins: [
// ... 其他插件
new OfflinePlugin()
]
接着在我们的入口文件main.js加入:
import * as OfflinePluginRuntime from 'offline-plugin/runtime';
OfflinePluginRuntime.install();
这样子直接跑webpack就ok了,试一下谷歌浏览器offline模式,你会发现还是能跑
需要注意的是vue cli3 是基于workbox来实现PWA
vue add pwa
registerServiceWorker.js:负责注册service work
service-worker.js:自定义的service work配置文件
/* eslint-disable no-console */
import {register} from 'register-service-worker';
if ('serviceWorker' in window.navigator && process.env.NODE_ENV === 'production') {
register(`${process.env.BASE_URL}service-worker.js`, {
ready() {
console.log(
'App is being served from cache by a service worker.\n' +
'For more details, visit https://goo.gl/AFskqB'
);
},
registered() {
console.log('Service worker has been registered.');
},
cached() {
console.log('Content has been cached for offline use.');
},
updatefound() {
console.log('New content is downloading.');
},
updated() {
console.log('New content is available; please refresh.');
},
offline() {
console.log('No internet connection found. App is running in offline mode.');
},
error(error) {
console.error('Error during service worker registration:', error);
}
});
}
import './registerServiceWorker'
User-agent: *
Disallow:
{
"name": "新华社",
"short_name": "新华社",
"icons": [
{
"src": "/img/icons/android-chrome-192x192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/img/icons/android-chrome-512x512.png",
"sizes": "512x512",
"type": "image/png"
}
],
"start_url": "/",
"display": "standalone",
"background_color": "#000000",
"theme_color": "#4DBA87"
}
if (workbox) {
console.log(`Yay! Workbox is loaded!`);
} else {
console.log(`Boo! Workbox didn't load!`);
}
// 设置缓存前缀和后缀,请根据实际项目名修改
workbox.core.setCacheNameDetails({
prefix: 'easy-front-vue-cli3',
suffix: 'v1.0.0'
});
// have our sw update and control a web page as soon as possible.
workbox.core.skipWaiting(); // 强制等待中的 Service Worker 被激活
workbox.core.clientsClaim(); // Service Worker 被激活后使其立即获得页面控制权
// vue-cli3.0 supports pwa with the help of workbox-webpack-plugin, we need to get the precacheing list through this sentence.
workbox.precaching.precacheAndRoute(self.__precacheManifest || []);
workbox.routing.registerRoute(
// Cache CSS files
/.*\.css/,
// 使用缓存,但尽快在后台更新
workbox.strategies.staleWhileRevalidate({
// 使用自定义缓存名称
cacheName: 'css-cache'
})
);
workbox.routing.registerRoute(
// 缓存JS文件
/.*\.js/,
// 使用缓存,但尽快在后台更新
workbox.strategies.staleWhileRevalidate({
// 使用自定义缓存名称
cacheName: 'js-cache'
})
);
workbox.routing.registerRoute(
/\.(?:png|gif|jpg|jpeg|svg)$/,
workbox.strategies.staleWhileRevalidate({
cacheName: 'images',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 60,
maxAgeSeconds: 30 * 24 * 60 * 60 // 30 Days
})
]
})
);
// 获取cdn上的资源,支持跨域,按自己的域名规则进行配置
workbox.routing.registerRoute(
/^http:\/\/www\.xinhuaimage\.com\/img\/.*\.(jpe?g|png|gif|svg)/,
workbox.strategies.staleWhileRevalidate({
cacheName: 'cdn-images',
plugins: [
new workbox.expiration.Plugin({
maxEntries: 60,
maxAgeSeconds: 5 * 24 * 60 * 60 // 5 Days
})
],
fetchOptions: {
credentials: 'include'
}
})
);
//缓存主站路由,按自己域名规则进行配置
workbox.routing.registerRoute(
// Vue
new RegExp('http://www.xinhuaimage.com'),
// 使用缓存,但尽快在后台更新
workbox.strategies.staleWhileRevalidate()
);
// api缓存,优选从网络获取,网络异常时再使用缓存,请根据实际api url配置RegExp,只支持get请求
workbox.routing.registerRoute(
new RegExp('http://www.xinhuaimage.com'),
workbox.strategies.staleWhileRevalidate({
plugins: [
new workbox.cacheableResponse.Plugin({
statuses: [0, 200]
})
]
})
);
// api缓存,优选从网络获取,网络异常时再使用缓存,请根据实际api url配置RegExp,支持post请求
// const bgSyncPlugin = new workbox.backgroundSync.Plugin('apiQueue', {
// maxRetentionTime: 1 * 60
// });
// workbox.routing.registerRoute(
// /.*\/api\/.*/,
// new workbox.strategies.NetworkOnly({
// plugins: [bgSyncPlugin]
// }),
// 'POST'
// );
/* eslint-disable no-console */
import {unregister} from 'register-service-worker';
if ('serviceWorker' in window.navigator && (process.env.NODE_ENV === 'production' || process.env.NODE_ENV === 'test' || process.env.NODE_ENV === 'pre-release')) {
unregister();
}
pwa: {
name: '新华社',
themeColor: '#4DBA87',
msTileColor: '#000000',
appleMobileWebAppCapable: 'yes',
appleMobileWebAppStatusBarStyle: 'black',
// configure the workbox plugin (GenerateSW or InjectManifest)
workboxPluginMode: 'InjectManifest',
workboxOptions: {
// swSrc is required in InjectManifest mode.
swSrc: 'src/service-worker.js',
importWorkboxFrom: 'disabled',
importScripts: 'https://cdn.myun.info/workbox-v4.3.1/workbox-sw.js'
// ...other Workbox options...
}
},
workboxPluginMode:workbox的模式,GenerateSW使用默认模式,InjectManifest使用自定义模式,我推荐使用InjectManifest,自由度更大
workboxOptions.swSrc: 指定service-worker.js所在位置
workboxOptions.importWorkboxFrom: 引入workbox依赖库的方式,默认的依赖库在Google的cdn上,国内情况大家都懂,因此建议将依赖库放到大家自己的cdn上,所以我这里设置了disabled
workboxOptions.importScripts: 指定你自己的依赖库的cdn的url