Vite 项目里启动 PWA


很简单,使用 vite-plugin-pwa 插件,Antfu 出品,品质保证。零配置,简单易用。

0. 安装插件

pnpm i vite-plugin-pwa -D

1. 启动插件

修改 vite.config.ts

import { VitePWA} from 'vite-plugin-pwa';
import { definePlugin } from 'vite';
import vue from '@vitejs/plugin-vue';

export default definePlugin(({ command }) => {
  const isDev = command === 'serve';
  return {
    plugins: [
      vue(),
      new VitePWA({
        disable: isDev, // 开发环境不启动 pwa
        includeAssets: [
          // 非直接加载,但是需要预缓存的内容
        ],
      }),
    ],
  };
})

2. 可脱机提示及可更新提示

原则上来说,Vite、Vite 插件都是开发脚手架,不限定框架。不过我用的最多的还是 Vue。这里以 Vue3 为例示范一下如何使用插件快速实现 PWA 组件:

  1. pwa 完成缓存后,提示可脱机使用
  2. 线上版本更新后,提示有新版本可用
  3. 更新时,给出视觉反馈
<script setup lang="ts">
import { useRegisterSW } from 'virtual:pwa-register/vue'
import {ref} from "vue";
const {
  offlineReady,
  needRefresh,
  updateServiceWorker,
} = useRegisterSW({
  immediate: true,
  onRegistered(r) {
    // 每小时自动检查一次,是否有新版本
    r && setInterval(async() => {
      await r.update()
    }, 60 * 60 * 1000)
  },
});
const isRefreshing = ref<boolean>(false);
function doRefresh() {
  isRefreshing.value = true;
  updateServiceWorker();
}
const close = () => {
  offlineReady.value = false
  needRefresh.value = false
}
</script>

<template lang="pug">
.pwa-toast.fixed.right-4.bottom-4.p-3.border.border-gray-200.rounded.bg-white.z-index-10.shadow-md(
  v-if="offlineReady || needRefresh"
  role="alert"
)
  p.message.mb-2
    span(v-if="offlineReady") App ready to work offline
    span(v-else-if="isRefreshing") Refreshing...
    span(v-else) New content available, click on reload button to update.
  button.border.border-gray-200.rounded.py-1.px-2(
    v-if="needRefresh",
    type="button",
    :disabled="isRefreshing",
    @click="doRefresh",
  )
    .spinner(v-if="isRefreshing")
    template(v-else) Reload
  button.border.border-gray-200.rounded.py-1.px-2.ml-2(type="button" @click="close") Close
</template>

3. 一些坑

  1. PWA 会拦截所有请求,以便缓存到本地。所以,打开网站,注册完 service worker,再请求其它文件,比如 ads.txt,也可能会看不到。这并不影响广告,因为广告商服务器不会受 PWA 影响;但是广告商运营人员可能只会操作浏览器,她们可能会认为你的广告文件没准备好。此时,请告诉她们使用匿名窗口。
  2. PWA 会自动预缓存 dist 目录内的东西,所以一定要注意 build.emptyOutDir,不要让目录过分膨胀,影响新用户体验。
  3. 有新版本后,上面的组件会提示用户刷新,但是刷新过程可能很慢(清理缓存,下载新内容等),所以点完之后可能没有反应。所以最好加上 spinner。

4. 总结&扩展阅读

整体来说,这个插件很好用,没什么特别需求的话,几乎可以零配置。

建议感兴趣的同学好好阅读下 官方文档,尤其是 examples 目录里的内容,会有很大帮助。


欢迎吐槽,共同进步

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

%d 博主赞过: