Skip to content

定期更新 Service Worker

信息

如果你没有从 vite-plugin-pwa 中导入任何虚拟模块,那么你需要自行配置它,这不在本指南的范围内

Service Worker 生命周期 一文的手动更新一节中解释了如何使用以下代码在您的 main.tsmain.js 上为您的应用程序配置定期 service worker 更新:

main.ts / main.js
ts
import { registerSW } from 'virtual:pwa-register';

const intervalMS = 60 * 60 * 1000;

const updateSW = registerSW({
  onRegistered(r) {
    r &&
      setInterval(() => {
        r.update();
      }, intervalMS);
  },
});

间隔必须以毫秒为单位,例如,上面的示例中将其配置为每小时检查 service worker

边缘情况处理

信息

从版本 0.12.8+ 开始,我们新增了一个选项 onRegisteredSW ,而 onRegistered 已被弃用。如果 onRegisteredSW 存在, onRegistered 将永远不会被调用

之前的脚本可以帮助您检查应用程序是否存在新版本,但是您还需要处理一些边缘情况,例如:

  • 当调用 update 方法时,服务器出现故障
  • 用户可以在任何时候断开网络连接。

为了解决之前的问题,可以使用下面这个更为复杂的片段:

main.ts / main.js
ts
import { registerSW } from 'virtual:pwa-register';

const intervalMS = 60 * 60 * 1000;

const updateSW = registerSW({
  onRegisteredSW(swUrl, r) {
    r &&
      setInterval(async () => {
        if (r.installing || !navigator) return;

        if ('connection' in navigator && !navigator.onLine) return;

        const resp = await fetch(swUrl, {
          cache: 'no-store',
          headers: {
            cache: 'no-store',
            'cache-control': 'no-cache',
          },
        });

        if (resp?.status === 200) await r.update();
      }, intervalMS);
  },
});

警告

这只适用于在导入任何虚拟模块或使用 workbox-window 模块时

因为 workbox-window 使用基于时间的 heuristic 算法来处理 service worker 更新,因此,如果您构建了自己的 service worker 并再次注册它,如果上次注册和本次注册之间的时间不足 1 分钟,那么workbox-window 将把 service worker update found 事件作为外部事件处理,因此可能会有很奇怪的行为(例如,如果使用 prompt ,将显示离线准备就绪的对话框,而不是显示新内容可用的对话框;如果使用 autoUpdate ,将显示离线准备就绪的对话框,然而它不应该显示)。

在MIT许可下发布.