webpack 中使用 workbox 实现 PWA
说明
重要文件版本
- “workbox-webpack-plugin”: “^3.0.0”
- “webpack”: “^3.11.0”
webpack 提供了 workbox 插件 workbox-webpack-plugin
webpack 中使用
在 production 版本配置中使用
1. 在入口 html 模板中引入
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="ie=edge,chrome=1">
<title>webpack-react-template</title>
<!-- 引入 manifest 文件 -->
<link rel="manifest" href="./manifest.json">
</head>
<body>
<div id="app"></div>
<script>
// 进行 service-wroker 注册
if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker
.register('./service-wroker.js')
.then(registration => {
console.log('SW registered: ', registration);
})
.catch(registrationError => {
console.log('SW registration failed: ', registrationError);
});
});
}
</script>
</body>
</html>
2. webpack.prod.config.js 中进行 webpack 配置
const WorkboxPlugin = require('workbox-webpack-plugin');
module.exports = merge(baseWebpackConfig, {
// ... 省略其他配置
plugins: [
// ... 省略其他配置
/*
这里也可以使用 WorkboxPlugin.InjectManifest({}) 配置
但是需要 配置 swSrc 指明模板 service-worker 文件
WorkboxPlugin.GenerateSW({}) 可以直接生成 service-worker 文件
*/
new WorkboxPlugin.GenerateSW({
cacheId: 'webpack-pwa', // 设置前缀
skipWaiting: true, // 强制等待中的 Service Worker 被激活
clientsClaim: true, // Service Worker 被激活后使其立即获得页面控制权
swDest: 'service-wroker.js', // 输出 Service worker 文件
globPatterns: ['**/*.{html,js,css,png.jpg}'], // 匹配的文件
globIgnores: ['service-wroker.js'], // 忽略的文件
runtimeCaching: [
// 配置路由请求缓存
{
urlPattern: /.*\.js/, // 匹配文件
handler: 'networkFirst' // 网络优先
}
]
})
]
});
注意:配置路由请求缓存,请看另外一篇文章
3. 转移 manifest.json 以及需要的图片
我这里使用了
copy-webpack-plugin
插件用于文件转移
new CopyWebpackPlugin([
{
from: 'src/manifest.json',
to: 'manifest.json'
},
{
from: 'src/icon.png',
to: 'static/imgs/icon.png'
}
]);
4. 编译后生成的 service-worker 文件
importScripts(
'https://storage.googleapis.com/workbox-cdn/releases/3.0.0/workbox-sw.js'
);
importScripts('/test/precache-manifest.14cde9ce3f3a728b83652a5461e9fd24.js');
workbox.core.setCacheNameDetails({ prefix: 'webpack-pwa' });
workbox.skipWaiting();
workbox.clientsClaim();
self.__precacheManifest = [].concat(self.__precacheManifest || []);
workbox.precaching.suppressWarnings();
workbox.precaching.precacheAndRoute(self.__precacheManifest, {});
workbox.routing.registerRoute(
/.*\.js/,
workbox.strategies.networkFirst(),
'GET'
);