PWA 即渐进式 Web 应用程序
(Progressive Web App)
,是一种利用多种现代 Web 技术构建的,能够提供类似原生应用体验的 Web 应用。本文是我在网上找到的解决方案,可能还存在更简单的实现方式
在继续后续步骤前,需要先将 UniApp 项目打包为网站版本
主要涉及以下三个核心文件:service-worker.js
、manifest.json
和 index.html
。下面我们分别来看它们的作用和配置方式。
manifest.json
创建manifest.json文件
{
// PWA 的名称,它将显示在设备的主屏幕、应用启动器等位置。
"name": "Tim小屋",
// PWA 的简短名称,当空间有限时,如在设备主屏幕上图标下方显示的名称,会优先使用短名称
"short_name": "Tim",
// PWA 在不同设备和场景下使用的图标。可以指定多种尺寸的图标,以适应各种屏幕分辨率和设备类型
"icons": [
{
"src": "/static/images/logo1.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "/static/images/logo2.png",
"sizes": "512x512",
"type": "image/png"
}
],
// 通常是应用的首页或主要入口点指定 PWA 启动时加载的 URL。通常是应用的首页或主要入口点
"start_url": "/",
// 有多种模式可供选择,如`fullscreen`(全屏显示)、`standalone`(类似原生应用)、`minimal-ui`(简约模式)
"display": "standalone",
// 启动时的背景颜色,在应用启动瞬间或加载过程中显示。
"background_color": "#ffffff",
// 定义 PWA 的主题颜色,它将影响浏览器的地址栏、任务栏等界面元素的颜色。
"theme_color": "#000000"
}
添加到网站
直接将 manifest.json
文件放到网站文件根目录下即可。
service-worker.js
创建service-worker.js文件
/* eslint-disable no-undef*/
importScripts('https://storage.googleapis.com/workbox-cdn/releases/5.1.2/workbox-sw.js')
if (workbox) {
console.log(`Yay! Workbox is loaded 🎉`)
} else {
console.log(`Boo! Workbox didn't load 😬`)
}
workbox.core.setCacheNameDetails({
prefix: 'chase-search',
suffix: 'v1.0.0'
})
workbox.core.skipWaiting() // 强制等待中的 Service Worker 被激活
workbox.core.clientsClaim() // Service Worker 被激活后使其立即获得页面控制权
workbox.precaching.precacheAndRoute(self.__precacheManifest || [{
url: '/',
revision: '1'
},
{
url: '/index.html',
revision: '1'
}
]) // 设置预加载
// 缓存web的css资源
workbox.routing.registerRoute(
// Cache CSS files
/.*\.css/,
// 使用缓存,但尽快在后台更新
new workbox.strategies.StaleWhileRevalidate({
// 使用自定义缓存名称
cacheName: 'css-cache'
})
)
// 缓存web的js资源
workbox.routing.registerRoute(
// 缓存JS文件
/.*\.js/,
// 使用缓存,但尽快在后台更新
new workbox.strategies.StaleWhileRevalidate({
// 使用自定义缓存名称
cacheName: 'js-cache'
})
)
// 缓存web的图片资源
workbox.routing.registerRoute(
/\.(?:png|gif|jpg|jpeg|svg|ico)$/,
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'images-cache',
plugins: [
new workbox.expiration.ExpirationPlugin({
maxEntries: 60,
maxAgeSeconds: 30 * 24 * 60 * 60 // 设置缓存有效期为30天
})
]
})
)
// 如果有资源在其他域名上,比如cdn、oss等,这里做单独处理,需要支持跨域
workbox.routing.registerRoute(
// /^https:\/\/blog\.timoxo\.cn\/.*\.(jpe?g|png|gif|svg)/,
/^https:\/\/([a-zA-Z0-9-]+\.)*timoxo\.[a-zA-Z]+\/.*\.(jpe?g|png|gif|svg)$/,
new workbox.strategies.StaleWhileRevalidate({
cacheName: 'cdn-images-cache',
plugins: [
new workbox.expiration.ExpirationPlugin({
maxEntries: 60,
maxAgeSeconds: 5 * 24 * 60 * 60 // 设置缓存有效期为5天
})
],
fetchOptions: {
credentials: 'include' // 支持跨域
}
})
)
添加到网站
直接将 service-worker.js
文件放到网站文件根目录下即可。
index.html
引入manifest.json文件
在 head
中添加引用:
<link rel="manifest" href="/manifest.json">
注册service-worker.js文件
<body><noscript><strong>Please enable JavaScript to continue.</strong></noscript>
<div id="app"></div>
<!-->注册<-->
<script defer="defer">
if ('serviceWorker' in navigator) {
navigator.serviceWorker.register('/service-worker.js')
.then(function(registration) {
console.log('Service Worker注册成功');
})
.catch(function(error) {
console.log('Service Worker注册失败:', error);
});
}
</script>
</body>
效果
最终的网站目录结构应如下:
部署到服务器后,浏览器若出现以下提示,即表示配置成功~
需要浏览器支持,图上是Edge浏览器
参考
许可协议:
CC BY 4.0