与服务人员互动推送通知 [英] React w/ Service Worker & Push Notifications

查看:89
本文介绍了与服务人员互动推送通知的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

一些初始注意事项:

"react": "^16.8.2",
"react-scripts": "2.1.5"

我创建了一个新的react应用,我需要实现Push Notifications 。
按照教程,我能够起床并在5分钟内运行,但是现在我必须在React应用中实施相同的策略(kinda)。

I have created a new react app and I need to implement Push Notifications. Following this tutorial, I was able to get up and running in 5 minutes, but now I have to implement the same strategy (kinda) into a react app.

我面临的问题是我能够订阅到Notification API,但是我不确定如何编辑 service-worker.js 文件以添加事件侦听器来捕获 push 事件(Google指南中的处理推送事件一章)

The problem I am facing is that I am able to subscribe to the Notification API, but I'm not sure how to edit the service-worker.js file to add an event listener to catch the push event (Handle a Push Event chapter in the google guide)

推荐答案

可以使用Create React App自定义您的服务人员,但可能相当困难且棘手。

Customizing your service worker with Create React App is possible, but could be quite difficult and hacky.

CRA使用开箱即用的 href = https://developers.google.com/web/tools/workbox/modules/workbox-webpack-plugin#generatesw_plugin_1 rel = noreferrer> GenerateSW webpack插件以生成 service-worker.js 文件,您无法向其中注入任何代码(您可以从CRA @ 2开始)

Out of the box, CRA uses Workbox GenerateSW webpack plugin to generate service-worker.js file, and you cannot inject any code to it (you could with CRA@1, not any more with since CRA@2)

您有几种策略,我将从最简单的策略开始。

You have several strategies, I'll start with the simplest one.


  • >启用服务工作者:

  • in src/index.js enable service worker:
// serviceWorker.unregister()
serviceWorker.register()


  • src / serviceWorker.js 中注册您的自定义文件:

  • in src/serviceWorker.js register your custom file:

    // if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
    if ('serviceWorker' in navigator) {
    



    // const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
    const swUrl = `${process.env.PUBLIC_URL}/custom-service-worker.js`;
    

    在运行开发服务器时必须更改名称原因,CRA提供了模拟 for service-worker.js

    You have to change the name cause when running dev server, CRA provides a mock for service-worker.js

    public / 文件夹中,创建 custom-service- worker.js 文件。 Webpack将按原样复制 build / 文件夹

    in public/ folder, create custom-service-worker.js file. Webpack will copy it as is in the build/ folder

    优点 :快速,肮脏的胜利

    Pros: quick, dirty win

    缺点 :您的自定义文件未使用Webpack处理(没有导入),并且由于绕过Workbox插件,您必须自己实现网络缓存逻辑(假设您需要PWA)

    Cons: your custom file is not processed with Webpack (no imports), and you must implement the network caching logic by yourself (assuming you want a PWA) since you're bypassing Workbox plugins

    有一个适用于它的模块: cra-append-sw
    您负责提供附加的代码。

    There's a module for it: cra-append-sw. You're in charge to provide the appended code.

    专业人士 :设置简便,需要优点GenerateSW

    Pros: easy setup, takes advantages GenerateSW

    缺点 :附加的代码使用Babel / Webpack处理,但不使用CRA的配置(您可以选择退出)。仍然使用GenerateSW为您处理网络缓存。不确定在本地开发时是否有效

    Cons: appended code is processed with Babel/Webpack, but not using CRA's config (you could opt-out). Still use GenerateSW which handle network caching for you. Not sure it works when developing locally


    • 应用解决方案#1的前两个步骤:更改 src / index.js src / serviceWorker.js

    中,创建 custom -service-worker.js 文件。它将由Webpack处理,因此您可以使用ES2016 / TypeScript语法并导入模块

    in src/ folder, create custom-service-worker.js file. It will be processed by Webpack, so you can use ES2016/TypeScript syntax and import modules

    /* eslint no-restricted-globals: "off" */
    import * as precaching from 'workbox-precaching'
    // your own imports
    
    if (self.__precacheManifest) {
    precaching.precacheAndRoute(self.__precacheManifest)
    }
    
    // your own code
    


  • install react-app-rewire


    • npm add --save-dev react-app-rewired

    • 放在 package.json 中,放在 scripts 中,替换 react-scripts react-app-rewired c>

    • npm add --save-dev react-app-rewired
    • in package.json, in "scripts", replace react-scripts with react-app-rewired

    调整webpack配置:在根文件夹中创建 config-overrides.js

    tweak webpack configuration: create config-overrides.js in root folder:

    const WebpackBeforeBuildPlugin = require('before-build-webpack')
    const WorkboxWebpackPlugin = require('workbox-webpack-plugin')
    const path = require('path')
    const merge = require('lodash.merge')
    const fs = require('fs')
    
    // from https://www.viget.com/articles/run-multiple-webpack-configs-sequentially/
    class WaitPlugin extends WebpackBeforeBuildPlugin {
    constructor(file, interval = 100, timeout = 60e3) {
     super(function(stats, callback) {
       const start = Date.now()
    
       function poll() {
         if (fs.existsSync(file)) {
           callback()
         } else if (Date.now() - start > timeout) {
           throw Error(`Couldn't access ${file} within ${timeout}s`)
         } else {
           setTimeout(poll, interval)
         }
       }
       poll()
     })
    }
    }
    
    const swOutputName = 'custom-service-worker.js'
    const workerSource = path.resolve(__dirname, 'src', swOutputName)
    
    module.exports = {
    webpack: (config, env) => {
     // we need 2 webpack configurations:
     // 1- for the service worker file.
     //    it needs to be processed by webpack (to include 3rd party modules), and the output must be a
     //    plain, single file, not injected in the HTML page
     const swConfig = merge({}, config, {
       name: 'service worker',
       entry: workerSource,
       output: {
         filename: swOutputName
       },
       optimization: {
         splitChunks: false,
         runtimeChunk: false
       }
     })
     delete swConfig.plugins
    
     // 2- for the main application.
     //    we'll reuse configuration from create-react-app, without a specific Workbox configuration,
     //    so it could inject workbox-precache module and the computed manifest into the BUILT service-worker.js file.
     //    this require to WAIT for the first configuration to be finished
     if (env === 'production') {
       const builtWorkerPath = path.resolve(config.output.path, swOutputName)
       config.name = 'main-application'
       config.plugins.push(
         new WorkboxWebpackPlugin.InjectManifest({
           swSrc: builtWorkerPath,
           swDest: swOutputName
         }),
         new WaitPlugin(builtWorkerPath)
       )
     }
    
     // remove Workbox service-worker.js generator
     const removed = config.plugins.findIndex(
       ({ constructor: { name } }) => name === 'GenerateSW'
     )
     if (removed !== -1) {
       config.plugins.splice(removed, 1)
     } 
    
     const result = [swConfig, config]
     // compatibility hack for CRA's build script to support multiple configurations
     // https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/scripts/build.js#L119
     result.output = { publicPath: config.output.publicPath }
     return result
    }
    }
    


  • 优点 :您可以在service-worker文件中使用ES2016 / TypeScript代码。您仍然可以从Workbox网络缓存功能中受益,对其进行完全控制

    Pros: you can use ES2016/TypeScript code in service-worker file. You still benefit from Workbox network caching facilities, with total control on it

    缺点 :复杂而脆弱,因为

    Cons: complicated and fragile, because of the multiple configuration hack.

    我使用了最后一个解决方案,因为我既需要从Workbox缓存代码,又需要一些 import 在我的服务工作者文件中。

    I've used the last solution, cause I needed both caching code from Workbox and some import in my service worker file.

    react-app-rewire-workbox 可能有助于简化Webpack配置(用于主应用程序的配置)。要测试。

    react-app-rewire-workbox may help simplifying the Webpack configuration (the one for main app). To be tested.

    这篇关于与服务人员互动推送通知的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆