如何将事件侦听器添加到 create-react-app 默认 sw.js 文件

Mos*_*imi 4 reactjs service-worker progressive-web-apps

我想使用模块默认的 service-worker ( sw.js) 文件Create-React-App

sw.js 文件类似于以下代码:

const isLocalhost = Boolean(
  window.location.hostname === 'localhost' ||
    window.location.hostname === '[::1]' ||
    window.location.hostname.match(
      /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
    )
);

export function register(config) {
  if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
    console.log('[Service Worker] Service Worker Registered!');
    const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
    if (publicUrl.origin !== window.location.origin) {
      return;
    }

    window.addEventListener('load', () => {
      const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;

      if (isLocalhost) {
        checkValidServiceWorker(swUrl, config);

        navigator.serviceWorker.ready.then(() => {
          console.log(
            'hello'
          );
        });
      } else {
        registerValidSW(swUrl, config);
      }
    });

  }
}

function registerValidSW(swUrl, config) {
  navigator.serviceWorker
    .register(swUrl)
    .then(registration => {
      registration.onupdatefound = () => {
        const installingWorker = registration.installing;
        if (installingWorker == null) {
          return;
        }
        installingWorker.onstatechange = () => {
          if (installingWorker.state === 'installed') {
            if (navigator.serviceWorker.controller) {
              console.log(
                'link'
              );

              if (config && config.onUpdate) {
                config.onUpdate(registration);
              }
            } else {
              console.log('Content is cached for offline use.');

              if (config && config.onSuccess) {
                config.onSuccess(registration);
              }
            }
          }
        };
      };
    })
    .catch(error => {
      console.error('Error during service worker registration:', error);
    });
}

function checkValidServiceWorker(swUrl, config) {
  fetch(swUrl)
    .then(response => {
      const contentType = response.headers.get('content-type');
      if (
        response.status === 404 ||
        (contentType != null && contentType.indexOf('javascript') === -1)
      ) {

        navigator.serviceWorker.ready.then(registration => {
          registration.unregister().then(() => {
            window.location.reload();
          });
        });
      } else {
        registerValidSW(swUrl, config);
      }
    })
    .catch(() => {
      console.log(
        'No internet connection found. App is running in offline mode.'
      );
    });
}

export function unregister() {
  if ('serviceWorker' in navigator) {
    navigator.serviceWorker.ready.then(registration => {
      registration.unregister();
    });
  }
}
Run Code Online (Sandbox Code Playgroud)

我想要的是向该文件添加更多事件侦听器,我已经尝试了上述代码的不同部分来添加侦听器,但它不起作用!作为一个例子,我添加了以下内容,但我不知道它应该放在哪里才能正常工作:

window.addEventListener('fetch', (e){
    console.log('[service worker] fetch')
})
Run Code Online (Sandbox Code Playgroud)

其他事件有installactivatebeforeinstallprompt等。

我问这个问题的主要目的是了解如何将安装横幅添加到我的反应项目中!

Kha*_*man 5

您无法在不弹出的情况下修改 create-react-app 中生成的 Service Worker 文件。作为解决方法,您可以创建一个 sw-epilog.js 文件,在其中添加所有 Service Worker 特定代码并在 package.json 中包含一个脚本将该文件附加到生成的服务工作线程文件中,如https://github.com/facebook/create-react-app/issues/5890#issuecomment-450915616中所述

我有一个要点在这里演示https://gist.github.com/khaledosman/de3535c8873831153efdf6c10a4b4080请参阅最后两个文件

// sw-epilog.js
// Add a listener to receive messages from clients
self.addEventListener('message', function(event) {
  // Force SW upgrade (activation of new installed SW version)
  if ( event.data === 'skipWaiting' ) {
    self.skipWaiting();
  }
});
Run Code Online (Sandbox Code Playgroud)
//package.json
"scripts": {
  "build": "rm -rf build/ && react-scripts build && npm run-script sw-epilog",
  "sw-epilog": "cat src/sw-epilog.js >> build/service-worker.js",
},
Run Code Online (Sandbox Code Playgroud)

对于完整的实现,您还可以查看https://github.com/khaledosman/create-react-pwa