【问题标题】:How to add event listeners to create-react-app default sw.js file如何将事件侦听器添加到 create-react-app 默认 sw.js 文件
【发布时间】:2019-07-24 14:51:02
【问题描述】:

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

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();
    });
  }
}

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

window.addEventListener('fetch', (e){
    console.log('[service worker] fetch')
})

其他事件有installactivatebeforeinstallprompt等。

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

【问题讨论】:

  • 为了达到您的主要目的,您可以在 index.js 中添加 window.addEventListener('beforeinstallprompt', (e) => { 而不是在 serviceWorker.js 上,但添加 fetch 事件侦听器是另一回事!我还能做到! :)
  • @ajafari 谢谢艾哈迈德!我的问题刚刚解决,我的朋友。

标签: reactjs service-worker progressive-web-apps


【解决方案1】:

您不能在不弹出的情况下修改 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();
  }
});
//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",
},

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

【讨论】:

  • 谢谢Khaled,您能否给我详细说明一下如何操作?例如是否有必要从我的目录中删除 sw.js 文件?然后如何将其注册为 service worker 到 navigator?
  • @MostafaGhadimi create-react-app 创建的 sw.js 文件不是浏览器使用的真正的 service worker 文件,它负责注册 service worker 并监听它的生命周期更新,真正的service worker 文件是由一个 webpack 插件生成的是,或者如果你想拦截 sw 生命周期来做某事,可以选择配置,看看 build/service-worker.js 在构建之后
  • 你的意思是需要构建项目?是否有另一种方法可以在开发模式下对其进行测试?
  • 不,Service Worker 的要求之一是他们需要通过 https 服务(localhost 是一个例外),要在本地测试我个人所做的是 npm i -g serve npm run build cd build/ && serve我在上面分享的代码 sn-p 向用户显示了应用程序已通过更新按钮更新的通知,否则服务工作者只会在应用程序运行的所有选项卡都关闭并重新打开应用程序时自行更新,请参见facebook.github.io/create-react-app/docs/…
猜你喜欢
  • 2021-04-17
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-19
  • 2021-03-31
相关资源
最近更新 更多