Workbox Service Worker手动更新流程

问题描述

这是我在sw注册和刷新的反应温泉中的实现。

问题是当我在当前sw上触发手动更新并接受新版本时(例如在活动sw中发送发布消息SKIP WAITING事件) 在激活新的软件后,我看不到controlling事件被触发

import { useEffect,useRef } from 'react';
import { WorkBox,messageSW } from 'workBox-window';

const SW_PATH = `${process.env.PUBLIC_PATH}sw.js`;

export const useSWRegisterOnMount = (param: {
  createUIPrompt: (opts: { onAccept: () => void }) => void;
}): {
  wb?: InstanceType<typeof WorkBox>;
  registration?: ServiceWorkerRegistration;
} => {
  const history = useHistory();

  const wb = useRef<InstanceType<typeof WorkBox>>();
  const registration = useRef<ServiceWorkerRegistration>();

  useEffect(() => {
    /** https://developers.google.com/web/tools/workBox/guides/advanced-recipes */
    if ('serviceWorker' in navigator) {
      wb.current = new WorkBox(SW_PATH,{
        scope: process.env.PUBLIC_PATH
      });

      const showSkipwaitingPrompt = (): void => {
        param.createUIPrompt({
          onAccept: () => {
            // this works perfectly when app is reopened
            // but in case of manual update service worker(workBox-window?) can skip emitting
            // of this "controlling" (also "activate") event but sw get activated in devtools 
            // application sw panel 
            wb.current?.addEventListener('controlling',() => {
              window.location.reload();
            });

            if (registration.current?.waiting) {
              messageSW(registration.current.waiting,{
                type: 'SKIP_WAITING'
              });
            }
          }
        });
      };

      wb.current.addEventListener('waiting',showSkipwaitingPrompt);
      wb.current.addEventListener('externalwaiting',showSkipwaitingPrompt);

      wb.current.register().then(swRegistration => {
        registration.current = swRegistration;
      });

      // https://developers.google.com/web/fundamentals/primers/service-workers/lifecycle#manual_updates
      setInterval(() => { // run manual updates
        registration.current?.update().then(() => {
          const sw = registration.current?.installing || registration.current?.waiting;

          if (sw) {
            showSkipwaitingPrompt();
          }
        });
      },1000 * 60 * 60);
    }
  },[]);

  return { wb: wb.current,registration: registration.current };
};

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)