Реагируйте с сервисным работником и push-уведомлениями - PullRequest
0 голосов
/ 19 февраля 2019

Некоторые первоначальные соображения:

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

Я создал новое приложение реагирования, и мне нужно реализовать Push-уведомления.После этого урока я смог начать работу за 5 минут, но теперь мне нужно внедрить ту же стратегию (своего рода) в приложение реагирования.

Проблема, с которой я сталкиваюсьзаключается в том, что я могу подписаться на API уведомлений, но я не уверен, как отредактировать файл service-worker.js, чтобы добавить прослушиватель событий, чтобы перехватить событие push (глава Handle a Push Event в руководстве Google)

1 Ответ

0 голосов
/ 08 марта 2019

Настройка вашего сервисного работника с помощью Create React App возможна, но может быть довольно сложной и хакерской.

Из коробки CRA использует Workbox GenerateSW плагин webpack для генерации service-worker.jsфайл, и вы не можете внедрить в него какой-либо код (вы могли бы с CRA @ 1, а не с CRA @ 2)

У вас есть несколько стратегий, я начну спростейший.

Решение 1: предоставьте свой собственный файл работника службы

  • в src/index.js включите работника службы:
    // serviceWorker.unregister()
    serviceWorker.register()
    
  • в src/serviceWorker.js зарегистрируйте свой пользовательский файл:

    // 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`;
    

    При запуске сервера dev необходимо изменить имя причины, CRA предоставляет mock для service-worker.js

  • в папке public/, создайте файл custom-service-worker.js.Webpack скопирует его как в папку build/

Плюсы : быстрый, грязный выигрыш

Минусы : ваш пользовательский файл не обрабатывается с помощью Webpack (без импорта), и вы должны самостоятельно реализовать логику сетевого кэширования (при условии, что вам нужен PWA), поскольку выобходят плагины Workbox

Решение 2: добавьте свой код к сгенерированному сервис-работнику

Для него есть модуль: cra-append-sw .Вы отвечаете за предоставление прилагаемого кода.

Плюсы : простота настройки, преимущества Преимущества GenerateSW

Минусы: добавленный код обрабатывается с помощью Babel / Webpack, но без использования конфигурации CRA (вы можете отказаться).Все еще используйте GenerateSW, который обрабатывает сетевое кэширование для вас.Не уверен, что он работает при локальной разработке

Решение 3: используйте Workbox в пользовательском файле служебного рабочего

  • примените первые 2 шага решения № 1: измените src/index.jsи src/serviceWorker.js

  • в папке src/, создайте файл custom-service-worker.js.Он будет обрабатываться Webpack, поэтому вы можете использовать синтаксис ES2016 / TypeScript и модули импорта

    /* eslint no-restricted-globals: "off" */
    import * as precaching from 'workbox-precaching'
    // your own imports
    
    if (self.__precacheManifest) {
    precaching.precacheAndRoute(self.__precacheManifest)
    }
    
    // your own code
    
  • установить реагировать на изменения в приложениях :

    • npm add --save-dev react-app-rewired
    • в package.json, в "scripts", замените react-scripts на react-app-rewired
  • настройка веб-пакета настройки: создать config-overrides.js в корневой папке:

    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
    }
    }
    

Pros : вы можете использовать код ES2016 / TypeScript в файле сервисного работника,Вы по-прежнему пользуетесь возможностями сетевого кэширования Workbox с полным контролем над ним

Минусы : сложные и хрупкие, из-за множественного взлома конфигурации.

Я использовал последнее решение, потому что мне требовался как кеширующий код из Workbox, так и немного import в моем файле рабочего сервиса.

act-app-rewire-workbox может помочь упроститьконфигурация Webpack (одна для основного приложения).Быть проверенным.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...