微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Workbox Service Worker手动更新流程

如何解决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 举报,一经查实,本站将立刻删除。