I have a PWA react app, which I can install like a PWA. So the PWA configuration seems to be setup correctly.
The service worker file is the same file generated when the project was created using create-react-app.

无论如何,我try 添加事件侦听器,但都没有添加:

function registerValidSW(swUrl, config) {
  navigator.serviceWorker.register(swUrl).then((registration) => {
    // This gets logged
    console.log("? ~ file: serviceWorker.js:168 ~ Registered service worker:");
    console.log(
      "? ~ file: serviceWorker.js:168 ~ navigator.serviceWorker.register ~ registration:",
      registration
    );

    registration.addEventListener("activate", function (event) {
      // This does not get logged
      console.log("? ~ file: Added 激活事件监听程序 to registration");
    });

    registration.addEventListener("push", async function (event) {
      // This does not get logged
      console.log("? ~ file: Added 推流事件监听器 to registration");
    });

    registration.addEventListener("fetch", (event) => {
      // This does not get logged
      console.log("? ~ file: Added 获取事件侦听器 to fetch");
    });
  });
}

激活事件监听程序

服务工作者被激活后,不会触发任何内容.

推流事件监听器

如果我发送推送通知,它不会被触发

获取事件侦听器

如果我打开一条路由,它不会被触发

知道发生了什么事吗?

推荐答案

我看到事件侦听器被添加到registration对象中.

但是像"激活"、"推送"和"获取"这样的事件应该在service worker本身内处理,而不是在注册对象上处理.

这意味着这将是not%的工作:

function registerValidSW(swUrl, config) {
  navigator.serviceWorker.register(swUrl).then((registration) => {
    // That gets logged
    console.log("? ~ file: serviceWorker.js:168 ~ Registered service worker:");
    console.log(
      "? ~ file: serviceWorker.js:168 ~ navigator.serviceWorker.register ~ registration:",
      registration
    );

    // Incorrect: Adding 'activate' event listener to registration object
    registration.addEventListener("activate", function (event) {
      // That does not get logged
      console.log("? ~ file: Added activate event listener to registration");
    });

    // Incorrect: Adding 'push' event listener to registration object
    registration.addEventListener("push", async function (event) {
      // That does not get logged
      console.log("? ~ file: Added push event listener to registration");
    });

    // Incorrect: Adding 'fetch' event listener to registration object
    registration.addEventListener("fetch", (event) => {
      // That does not get logged
      console.log("? ~ file: Added fetch event listener to fetch");
    });
  });
}

服务工作者文件是在服务工作者的上下文中运行的单独的JavaScript文件,而不是在页面的主线程中运行.

https://web-dev.imgix.net/image/RK2djpBgopg9kzCyJbUSjhEGmnw1/iKWO7c2WNobLt30VZx9C.png?auto=format&w=845

在页面的主线程中(例如,在serviceWorker.js文件中),注册服务工作者,就像您已经在做的那样.该部分负责注册服务工作者文件,不处理"激活"、"推送"和"获取"等服务工作者事件.

在服务工作者文件(例如,service-worker.js)中,您将为"Activate"、"Push"和"Fetch"添加事件侦听器.该文件应该与navigator.serviceWorker.register(swUrl)调用注册的文件相同.

例如:

// The 'activate' event
self.addEventListener('activate', event => {
  console.log("? ~ Service Worker activated!");
  // Your activation logic here
});

// The 'push' event
self.addEventListener('push', event => {
  console.log("? ~ Push event received!");
  // Your push logic here
});

// The 'fetch' event
self.addEventListener('fetch', event => {
  console.log("? ~ Fetch event triggered!");
  // Your fetch logic here
});

该代码应该放在不使用ES6导入或其他页面级代码的单独的JavaScript文件中,因为它将在服务工作者上下文中运行.

然后,您可以判断在触发相应事件时是否看到这些日志(log)消息.


我没有service-worker.js%的档案.

尽管如此,这是用于登记的swUrl:const swUrl = ${process.env.PUBLIC_URL}/service-worker.js; registerValidSW(swUrl, config);

Should I add it somewhere or something?
I'm also confused how come it doesn't exist, and the PWA setup works correct.

I see the "Create React App" (CRA) feature should automatically generate a service worker file for you when you opt into using a service worker (for example, by using the cra-template-pwa template or manually configuring it).
In a standard CRA setup, you don't have to write your own service worker file, but it does indeed exist and is usually generated during the build process.

由于在Create Reaction App(CRA)项目中生成的服务工作者文件通常是构建过程的一部分,并且每次构建项目时它都会被覆盖,这意味着如果您直接修改它,然后运行构建,...您所做的更改将丢失.

相反,您可以try 运行npm run eject(或yarn eject),这将公开所有配置文件,包括服务工作者文件.这允许您直接修改它,但缺点是必须自己管理整个构建配置.


另一种方法是创建您自己的自定义服务工作者文件并将其包含在您的项目中.您可以像生成的服务工作者一样注册它.确保在这个定制服务工作者中自己处理所有必要的缓存和其他PWA功能.

例如,要创建和注册自定义服务工作者(custom-sw.js):

// custom-sw.js (Your custom service worker file)
self.addEventListener('activate', event => {
  console.log("Custom service worker activated!");
});

self.addEventListener('push', event => {
  console.log("Custom push event received!");
});

self.addEventListener('fetch', event => {
  console.log("Custom fetch event triggered!");
});

然后,在您的serviceWorker.js文件中,您可以将注册URL更改为指向您的定制服务人员:

const swUrl = `${process.env.PUBLIC_URL}/custom-sw.js`;
registerValidSW(swUrl, config);

确保从正确的位置提供自定义服务工作者文件.您可能需要更新生成配置或将文件放在public文件夹中,具体取决于项目的 struct .


Or you can use Workbox: a set of libraries that can make service worker development easier, and it's often used with CRA to create custom service worker logic.
See "Making a Progressive Web App"

从Create Reaction App 4开始,您可以将src/service-worker.js文件添加到您的项目中,以使用对Workbox的InjectManifest插件的内置支持,该插件将编译您的服务工作器并向其中注入要预缓存的URL列表.


OP在 comments 中提到了页面"How to add event listeners to create-react-app default sw.js file",并补充道:

这要简单得多.您只需在构建完成后将监听程序附加到服务工作者文件

该方法有效地允许您将自定义代码注入到生成的服务工作者文件中,而不必直接修改它,保留了CRA构建过程的优势,同时仍然允许您灵活地添加自定义逻辑.

  • 您可以在一个单独的文件(如sw-epilog.js)中编写您的自定义服务工作者代码.这可能包括您想要附加到生成的服务工作进程中的事件侦听器或其他代码.

  • 在构建过程完成后,您可以使用package.json文件中的脚本将此自定义代码文件连接到生成的服务工作者文件的末尾.shell 命令cat src/sw-epilog.js >> build/service-worker.js中的>>操作符通过获取sw-epilog.js的内容并将其附加到service-worker.js的末尾来实现这一点.

  • 您可以在生成过程中包含此串联步骤,以便在每次生成项目时自动执行.

Reactjs相关问答推荐

有正确的方法来设置我的金牛座应用程序的图标吗?

react 表复选框不对任何操作做出react

两条react 路由的行为不同.有没有人能解释一下,我已经找了好几天了

将对象添加到集合中的数组时的no_id字段

页面永远加载API/从数据库获取数据

根据用户 Select 的注册类型更改表单字段

状态改变不会触发重新渲染

React 错误无法读取未定义的属性(读取id)#react

CORS策略:对预检请求的响应未通过访问控制判断:没有Access-Control-Allow-Origin

使用 toast 时挂钩调用无效

@react-three/postprocessing 没有匹配的从 three.module.js 导出以导入WebGLMultisampleRenderTarget

null 不是对象(判断RNSound.IsAndroid)

如何通过单击多个选项中的特定项目在模态上呈现不同的标题?

将 ref 赋予功能组件以使用内部功能

react-markdown 不渲染 Markdown

react 路由dom没有路由匹配位置错误/在路由中制作组件

React Hooks 表单在日志(log)中显示未定义的用户名

找不到元素 - 这是参考问题吗?

将 set statehook 函数传递给子路由组件.解构错误

如何防止 mui x-date-picker 被截断?