Как создать собственный PWA с помощью Workbox в приложении create-react-app

kak sozdat sobstvennyj pwa s pomoshhyu workbox v prilozhenii create react app

Примечание: Это третья из серии сообщений о PWA внутри React. Для быстрого начала смотрите две предыдущие публикации здесь и здесь.

В следующем сообщении я расскажу вам, как создать собственную прогрессивную веб-программу (PWA) с помощью библиотеки Google Workbox без извлечения из оболочки create-react-app (CRA).

Workbox – это набор библиотек, облегчающих создание автономных функций. Workbox также считается преемником sw-precache библиотеку, используемую CRA для создания программного обеспечения по умолчанию.

Были некоторые разговоры о миграции CRA sw-precache в Workbox (подробнее см. в этом вопросе). К сожалению, кажется, из этого еще ничего не вышло.

Цели

  1. Настройте сборку CRA с использованием react-app-rewired. (react-app-rewired — это библиотека для настройки сборки CRA по умолчанию без удаления)
  2. Используйте react-app-rewired, чтобы настроить сборку для использования Workbox для создания служащего
  3. Создайте очень простую программу для выполнения задач
  4. Реализуйте офлайн-функционал для программы задач с помощью Workbox.
    Оффлайн-функционал, на который мы будем ориентироваться:
    a) Кэшировать полученные ресурсы, чтобы их можно было обслуживать в автономном режиме
    b) Разрешить публикацию данных в автономном режиме

Представляем Workbox в CRA

Сначала создайте новый репозиторий CRA с помощью такой команды:

npx create-react-app react-app-rewire-workbox

Это должно создать новую папку с соответствующим названием. Настроив эту папку, перейдите в папку и создайте файл Service Worker в общедоступной папке. Я позвоню своим custom-service-worker.js.

Сделав это, удалите чек NODE_ENV устанавливается значение PRODUCTION внутри registerServiceWorker.js

Наконец, внутри custom-service-worker.js файл, вставьте следующий код:

Этот фрагмент кода я взял прямо с веб-сайта Workbox. Вы используете importScripts строка для ввода глобальной переменной с именем workbox в свой файл. Импортируемый сценарий обслуживается через CDN. Затем у вас есть простая проверка, правильно загружена переменная сценарием или нет.

Итак, сейчас у нас работает Workbox в среде разработчиков. Далее давайте разберемся, как реализовать react-app-rewired в CRA.

Реализация react-app-rewired в CRA

Добавьте react-app-rewired пакет в папку вашего проекта с помощью такой команды:

npm install --save-dev react-app-rewired

Теперь, если вы прочтете документы, они вспоминают, что вам нужно настроить a config-overrides.js файл в корневом каталоге вашего проекта. Давайте поначалу разберемся, что это делает.

Я создаю файл barebones и объясню вам, что это значит. В документации есть очень подробное объяснение, если вы хотите прочитать это вместо этого.

Вы можете экспортировать объект из этого файла с помощью трех ключей: webpack, jest, devServer. Подходящие функции позволяют настроить конфигурацию сервера производства веб-пакетов, конфигурацию файла и, наконец, конфигурацию сервера разработки веб-пакетов.

Если посмотреть на devServer ключ в config-overrides.js файл, вы заметите, что мы ведем журнал configFunction.toString() вместо просто configFunction . Это потому, что если вы попробуете последнее, Node просто напечатает [Function] к консоли.

Откройте свой package.json файл и замените команду scripts для начала с react-app-rewired start .

Создание программы Todo

Пока нам удалось ввести Workbox в нашу среду разработчиков, а также представили react-app-rewired в нашу оболочку CRA. Давайте оставим все как есть, создадим образец программы задач и запустим ее в среде разработчика.

Приложению todo понадобится несколько движущихся частей, чтобы мы могли реально использовать сервисных работников.

Это будет включать:

  1. Базовый слой пользовательского интерфейса (я собираюсь полностью игнорировать стили для этого.)
  2. А json-server мы можем запрашивать данные от

Я не буду удаваться слишком подробно о настройках, потому что все достаточно просто. Я включаю ссылку на репозиторию git с рабочей версией этой программы в конце этой статьи, чтобы вы могли посмотреть на это.

Вот компонент Todo, который я написал.

Компонент делает запрос на выборку до a json-server Я настроил и получил ответ, состоящий из массива задач. Компонент затем воспроизводит эти задачи. Как я уже сказал, очень просто.

Чтобы настроить json-server выполните следующую команду:

npm install --save json-server

Создайте файл под названием db.json с такой структурой

Наконец, проделайте следующую команду в терминале:

json-server --watch db.json --port 8000

Это запускает локальный сервер на порту 8000 и наблюдает за db.json файл для любых изменений. Если что-нибудь изменится, сервер перезапустится. Это очень простой способ высмеять сервер для тестирования вашего приложения.

Наконец, обновите свой App.js чтобы отобразить ваш новый компонент Todo, и удалите JSX по умолчанию из этого файла.

Запустите приложение (внутри окна в режиме анонимного просмотра) и посмотрите, как оно выглядит сейчас. Вы должны увидеть список задач и поле ввода под ними с кнопкой для отправки. Как я уже сказал, очень простой пользовательский интерфейс.

Когда вы все это настроите, давайте выясним как сделать так, чтобы эти вещи работали в автономном режиме с помощью Workbox.

Примечание: При тестировании функциональности Service Worker в среде разработчиков всегда убедитесь, что вы делаете это в новом окне анонимного просмотра каждый раз. Это делает тестирование и отладку гораздо меньшей проблемой, поскольку ваши данные не сохраняются между сеансами.

Реализация кэширования с помощью Workbox

Теперь, если вы откроете панель инструментов Chrome, вы увидите что-то вроде приведенного ниже на вкладке «Программа».

1*6M7SSHyjM_1Yf2GV8Dvk9A
Панель инструментов разработчика Google Chrome

Установите флажок в автономном режиме и попытайтесь перезагрузить веб-страницу. Вероятно, он выйдет из строя с сообщением об ошибке, что не обнаружено подключение к сети. Если вы посмотрите на вкладку сети, вы увидите кучу неудачных сетевых запросов.

Самый очевидный, терпящий неудачу, — это запрос к нашему. json-server чтобы получить список задач. Давайте сначала поправим это. Откройте custom-service-worker.js файл и добавьте следующий код

workbox.routing.registerRoute(  '  workbox.strategies.networkFirst())

Это настройка стратегии кэширования networkFirst для любых запросов, сделанных к конечная точка. Изображение ниже дает вам четкое объяснение того, что networkFirst Стратегия предполагает. Вы всегда сначала проверяете сеть, и только в случае сбоя сети вы переходите в кэш, чтобы получить ресурс. Это типичная стратегия, которую можно использовать при запросе API, который, вероятно, предоставляет новые данные.

1*xTraAJtPw5Cdb-SErJgBSYg
Стратегия Network First

Теперь приложение все еще не скачивается, потому что нам все еще не хватает двух важных элементов. А именно, мы все еще не кэшируем

  1. Пакет JS, обслуживаемый нашим локальным сервером разработчиков.
  2. The index.html файл

Добавьте следующий код в custom-service-worker.js

workbox.routing.registerRoute(
  /\.(?:js|css|html)$/,
  workbox.strategies.networkFirst(),
)
workbox.routing.registerRoute(
  workbox.strategies.networkFirst()
)

Если вы заметили, первый маршрут в приведенном выше фрагменте кода – это a RegEx объект. Это чистый и простой способ ориентироваться на несколько маршрутов с помощью одной стратегии. Однако, если вы нацеливаетесь на ресурс, не соответствующий той же политике происхождения, не забудьте указать весь маршрут.

Это, конечно, не идеальный способ делать вещи. В идеале мы хотим, чтобы статические активы, такие как пакеты JS, таблицы стилей и файлы HTML, предварительно кэшировались как часть процесса сборки Webpack. Мы дойдем до этого, но важно понять, что черной магии нет. Это все просто кэширование.

Идите и снова запустите страницу и откройте консоль. Вы должны увидеть кучу журналов Workbox о маршрутизации. Выделите автономный режим и обновите страницу. Вы должны видеть, как все загружается, как обычно. Если вы откроете журналы рабочего ящика на консоли, вы увидите, что Workbox распечатал, не удалось ли выполнить сетевой запрос, а также ответ рабочего ящика на ошибку (см. снимок экрана ниже):

1*deKoAAdcLbj8PjqykZNvsQ
Журнал Workbox в окне инструментов разработчика Chrome

Реализация отложенной публикации данных с помощью Workbox

Хорошо следующее: как мы публикуем данные обратно на сервер без подключения к сети?

Во-первых, давайте настроим способ отправки данных в Интернет и убедимся, что он работает. Обновите свой addTodo функция внутри вашего компонента Todo, чтобы она выглядела так:

Все, что мы сделали, это добавили обработчик обратного вызова setState чтобы мы могли быть уведомлены, когда состояние обновится. На данный момент мы запросили POST к json-server обновить db.json с новой задачей.

Попробуйте отправить новое задание, откройте db.json и вы должны увидеть новые задачи, добавленные к вашему массиву объектов.

Теперь попробуйте сделать то же самое в автономном режиме, и вы получите ошибку сети по понятным причинам. Вы, вероятно, получите оператор журнала, который говорит: Не удалось получить.

Чтобы решить эту проблему, мы будем использовать что-нибудь под названием backgroundSync, спецификацию которого вы можете прочитать здесь. Как он должен работать, это то, что каждый раз, когда вы делаете запрос на сервер по определенному ресурсу (в нашем случае запрос POST), если сеть не обнаружена, Workbox сохранит этот запрос в indexedDB и будет продолжать опрашивать запрос на набор промежуток времени. При обнаружении подключения к сети запрос будет воспроизведен повторно. Если в течение определенного периода времени не установлено подключение к сети, запрос отклоняется.

API backgroundSync использует что-то под названием SyncManager под капотом. Вы можете прочитать об этом в документации MDN здесь. К сожалению, как вы видите, SyncManager не отвечает стандартам, и Chrome является единственным браузером, который имеет полностью реализуемую спецификацию. Это означает, что Chrome является единственным браузером, в котором гарантированно работает надежно.

Нам нужно добавить код custom-service-worker.js чтобы материал backgroundSync работал на нас. Добавьте следующий код в файл:

Мы используем плагин фоновой синхронизации, который дает нам Workbox. Первым параметром, который вы предоставляете конструктору, является имя очереди, которую Workbox должен создать при сохранении неудачных запросов. Второй параметр – объект параметров, где мы определяем максимальное количество времени для попытки повторить запросы.

Наконец мы регистрируем новый маршрут с помощью метода POST и устанавливаем стратегию, которую мы хотим использовать для кэширования. Это очень похоже на то, что мы уже делали, кроме определения типа запроса, а также определения плагина для нашей стратегии.

Теперь попробуйте выполнить тот же сценарий отправки задачи без подключения к сети и понаблюдайте за происходящим в журнале. Вы получите журнал, который выглядит как на скриншоте ниже.

1*fga8x8OIE4dT8b4DMvBRIw
Workbox добавляет неудачный запрос в очередь

Вы можете просмотреть добавленный запрос, найдя indexedDB на вкладке приложения в окне Chrome DevTools. Откройте перечисленные подкаталоги в раскрывающемся меню indexedDB, и вы увидите сохраненный запрос, ожидающий повторного воспроизведения.

Выключите параметр офлайн в окне DevTools, и вы почти сразу увидите новое всплывающее окно журнала Workbox. Это будет выглядеть так:

1*C46elEi-gXvBXEwpy1INqw
Журнал рабочего ящика с подробной информацией о том, что неудачный запрос воспроизведен и отправлен

На рисунке выше показано, что Workbox воспроизводит неудачный запрос в момент получения запроса на синхронизацию и дает вам подтверждение того, что ваш запрос был успешным. Если посмотреть на db.json теперь вы заметите, что новая задача была добавлена ​​в файл.

Ну вот мы идем. Теперь у нас есть способ воспроизводить неудачные запросы через сервис-воркер.

Далее нам нужно интегрировать плагин Webpack, чтобы Workbox мог кэшировать статические активы как часть процесса сборки. Это избавит от необходимости явно иметь маршрут кэширования статических активов в нашем файле Service Worker.

Предварительное кэширование статических активов

Это будет последний шаг. В этом разделе мы собираемся внести изменения в процесс сборки CRA, чтобы заставить его создать файл Service Worker с помощью Workbox вместо sw-precache.

Сначала установите следующие пакеты: workbox-webpack-plugin и path.

Откройте package.json файл и отредактируйте сценарий сборки для запуска react-app-rewired вместо react-scripts так же, как мы сделали для стартового сценария.

Наконец, откройте config-overrides.js файл и отредактируйте его так:

В этом файле мы делаем несколько вещей.

Сначала мы проверяем, это производственная сборка. Если это так, мы создаем конфигурационный объект Workbox и предоставляем ему путь нашего пользовательского программного обеспечения и путь исходного программного обеспечения, которое мы желаем.

Мы также предлагаем вариант под названием importWorkboxFrom и установите его disabled.

Это параметр, который определяет, что мы не хотим, чтобы Workbox импортировали откуда-то, поскольку мы спрашиваем его непосредственно из CDN в нашем сценарии программного обеспечения.

Наконец, у нас есть функция, которая называется removeSWPrecachePlugin . Все, что это делает, это перебирает плагины, перечисленные в конфигурации Webpack, находит правильный и возвращает индекс, чтобы мы могли его удалить.

Теперь запустите сборку программы и откройте файл программного обеспечения, созданный в папке сборки. В моем случае этот файл программного обеспечения называется custom-service-worker.js

Вы заметите новое importScripts вызов в верхней части файла, который, кажется, запрашивает файл манифеста предыдущего кэша. Этот файл хранится в папке сборки, и если вы его откроете, вы увидите список всех статических ресурсов, кэшируемых Workbox.

Вывод

Итак, мы достигли следующих целей:

  1. Настройте сборку CRA на использование react-app-rewired
  2. Используйте react-app-rewired, чтобы настроить сборку для использования Workbox для создания Service Worker — мы добились этого с помощью workbox-webpack-plugin. Процесс сбора будет автоматически кэшировать все статические активы.
  3. Создайте очень простую программу для выполнения задач
  4. Реализуйте офлайн-функционал для программы задач с помощью Workbox.
    Оффлайн-функционал, на который мы будем ориентироваться:
    a) Кэшировать полученные ресурсы, чтобы их можно было обслуживать в автономном режиме
    b) Разрешить публикацию данных в автономном режиме

Вот ссылка на репо, содержащая рабочую версию программы. Вы можете клонировать это и поиграть с ним.

Следите за мной в Twitter здесь. Следите за мной на GitHub здесь

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *