在枝网前端寻找一个能够将站点PWA化的方案时,找到了 vite-plugin-pwa
安装
npm i -D vite-plugin-pwa
配置
// vite.config.ts
import { defineConfig } from 'vite'
// import other plugins
import { VitePWA } from 'vite-plugin-pwa'
export default defineConfig({
plugins: [
// other plugins
VitePWA({})
],
})
VitePWA接受一个 Partial<VitePWAOptions>
, 其中,必须配置的属性有
- base
- workbox
- manifest
这里是一个样例(使用枝网的配置)
VitePWA({
mode: 'development',
base: '/',
registerType: process.env.CLAIMS === 'true' ? 'autoUpdate' : undefined,
includeAssets: ['favicon.svg', 'robots.txt', 'apple-touch-icon.png'],
// 配置 worker box 用于离线缓存
workbox: {
runtimeCaching: [
{
// 根据正则表达式进行缓存,如果你喜欢 也可以使用/.*/i
urlPattern: /^https:\/\/asoulcnki.asia\/v1\/api\/ranking\/.*/i,
handler: 'NetworkFirst',
options: {
cacheName: 'asoulcnki-api-cache',
expiration: {
maxEntries: 10,
maxAgeSeconds: 60 * 60 * 1.5,
},
cacheableResponse: {
statuses: [0, 200],
},
},
}
],
},
manifest: {
name: '枝网查重',
short_name: '枝网查重',
theme_color: '#60A5FA', // 主题颜色,和 index.html 中的保持一致
background_color: '#FFFFFF',
description: 'A-Soul 小作文查重',
start_url: '/',
lang: 'zh-Hans-CN',
// PWA 要求至少有一张 192x192 和 512x512 的图片
icons: [
{
src: 'pwa-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: 'pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
},
{
src: 'pwa-512x512.png',
sizes: '512x512',
type: 'image/png',
purpose: 'any maskable',
},
],
},
}),
在 index.html 的header 添加以下内容
<link rel="apple-touch-icon" href="/pwa-192x192.png" />
<link rel="mask-icon" href="/favicon.svg" color="#FFFFFF" />
<meta name="msapplication-TileColor" content="#FFFFFF" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<!-- theme-color 和配置中的保持一致即可 -->
<meta name="theme-color" content="#60a5fa" />
之后运行 npm run build
或者你自己的构建命令
vite-plugin-pwa 会自动为你生成对应的 manifest 和 Service Worker
不过到这里还是有些问题,sw.js 不会自己注册
需要向 index.html 添加如下内容
<script src="/registerSW.js"></script>
Service Worker 的更新
这里使用的是最简单的做法,浏览器在每次启动时,会自动对比新的 sw.js 和本地的 sw.js, 如果存在差异,就进行更新
注意,对于sw.js,应该尽量避免通过修改文件名的方式来更新,因为两个不同版本的Service Woeker可能存在冲突问题
如果使用了CDN的话,需要将 sw.js 设置为不缓存
另外,PWA只有在 localhost 和 https 环境下可用
其他细节的地方后续再补充,先摆烂了