Горячая замена модуля в Redux

Опубликовано: 2022-03-11

Это минимальный пример горячей замены модуля (или HMR) в приложении Redux. Рабочий демо-код размещен на GitHub. Мы включаем только те настройки, которые необходимы для поддержки HMR, что упрощает применение HMR в вашем собственном приложении Redux.

Если вам не терпится применить HMR, перейдите в этот раздел, чтобы настроить HMR для вашего проекта в течение пяти минут!

Демонстрация замены горячего модуля

Запустите пример

Сначала испачкайте руки! Прежде чем запускать команды для запуска этого примера приложения, убедитесь, что Git, Node.js и Yarn правильно установлены на вашем компьютере.

 $ git clone https://github.com/Front-end-io/articles.git $ cd articles && git checkout redux-hmr $ yarn install $ yarn start

Затем посетите http://localhost:3000/, чтобы проверить, работает ли он.

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

Замена горячего модуля

Горячая замена модуля — одна из самых полезных функций, предлагаемых Webpack. Он позволяет обновлять все виды модулей, включая файлы JSON, CSS и JS, во время выполнения без необходимости полного обновления.

Вот как это работает внутри:

  1. Приложение просит среду выполнения HMR проверить наличие обновлений.
  2. Среда выполнения асинхронно загружает обновления и уведомляет приложение.
  3. Затем приложение просит среду выполнения применить обновления.
  4. Среда выполнения синхронно применяет обновления.

Схема замены горячего модуля

HMR повышает производительность при разработке приложения Redux. Redux — это контейнер с предсказуемым состоянием для приложений JavaScript. Это очень популярный современный фреймворк, основанный на React. Redux, по определению первого принципа Redux, представляет собой единственное хранилище общих данных, описанное в его документации как «Единый источник правды». Хранилище данных (простой объект JavaScript, обновляемый reducers ) будет обновляться по мере того, как пользователь работает с приложением. Каждая операция пользователя, такая как нажатие кнопки, загрузка внутренних данных и т. д., скорее всего, будет обновлять хранилище несколько раз. Нелегко исправить ошибку, когда ошибка возникает только с определенным снимком состояния.

HMR позволяет нам обновлять страницу без повторной инициализации глобального хранилища. Во время разработки Redux мы можем захотеть проверить хранилище после серии операций. Очень распространенный сценарий: ошибка возникает только после того, как мы добавили определенный (возможно, сложный) элемент в магазин. Без HMR мы должны сделать следующие шаги:

  1. Измените код, который потенциально вызывает ошибку.
  2. Обновите страницу, добавьте конкретный товар в магазин.
  3. Если ошибки сохраняются, повторите шаг 1.

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

Исправление ошибки не означает, что вам нужно перезапустить приложение с помощью HMR.

Примечание. В некоторых случаях модификация кода может повлиять на текущее значение хранилища. В этом случае HMR предупредит вас о необходимости перезагрузить всю страницу.

Функция в этом примере

Мы хотим, чтобы эта функция была минимальной, просто чтобы продемонстрировать возможности HMR. Таким образом, в этом приложении мы не включаем общие функции в приложение React, включая redux-logger, react-router-redux, redux-thunk, redux-devtools и т. д. Между тем, мы оставляем только один редюсер, два действия и 1 страница.

Наше приложение хранит в хранилище только значение счетчика. У нас есть только одна страница с именем home , на которой отображается значение счетчика и две кнопки для увеличения/уменьшения значения счетчика.

Чтобы убедиться, что HMR работает, просто увеличьте/уменьшите значение счетчика несколько раз, а затем измените код. Например, измените заголовок « Счетчик » на « Счетчик в магазине» . Тогда мы обнаружим, что:

  • Страница не обновляется.
  • Отображаемое значение счетчика НЕ ​​ИЗМЕНЯЕТСЯ.
  • Название было изменено на Прилавок в магазине .

‍ Настройте HMR за пять минут

Чтобы настроить HMR, выполните следующие действия.

Основные библиотеки

Эти библиотеки должны быть установлены для поддержки HMR:

  • react-hot-loader@^4.2.0: Скомпилируйте и обновите приложение React в режиме реального времени.
  • webpack-dev-server@^3.1.4: обслуживает приложение Webpack. Обновляет браузер при изменениях.

ES6

Если вы используете ECMAScript6 (а кто не использует в наши дни?), вам нужны дополнительные инструменты для компиляции ES6 в режиме реального времени. Во-первых, это минимальный файл конфигурации ES6 .babelrc:

 { "env": { "development": { "presets": [ "react-hmre" ] } } }

Для поддержки компиляции в реальном времени необходима эта библиотека:

  • предустановленная вавилонская реакция-hmre @ ^ 1.1.1

Webpack.config.js

Нам нужно настроить HMR в файле конфигурации Webpack webpack.config.js.

Во-первых, включите плагин HMR в разделе плагинов:

 "plugins": [ … new webpack.NamedModulesPlugin(), new webpack.HotModuleReplacementPlugin(), ]

Подключаемый модуль HMR создает манифест, файл JSON со списком обновленных модулей и обновление, файл JSON, содержащий данные, которые необходимо применить. Следует отметить, что HMR — это опция, предоставляемая Webpack. Загрузчики, такие как style-loader, которые реализуют интерфейс HMR, получают обновление через HMR, а затем заменяют старый код новым кодом.

Если мы используем webpack-dev-server, то нам нужно включить хот-флаг в разделе devServer:

 "devServer": [ ... hot: true, ]

Горячая перезагрузка редукторов Redux

Начиная с Redux версии 2.0.0, редукторы не неявно перезагружаются в горячем режиме, потому что неявная горячая перезагрузка вызывает некоторые проблемы. Если ваше состояние Redux сбрасывается до начальных значений при горячем обновлении, попробуйте включить горячее обновление для редукторов:

 import { createStore } from 'redux'; import rootReducer from '../reducers/index'; export default function configureStore(initialState) { const store = createStore(rootReducer, initialState); if (module.hot) { // Enable Webpack hot module replacement for reducers module.hot.accept('../reducers', () => { const nextRootReducer = require('../reducers/index'); store.replaceReducer(nextRootReducer); }); } return store; }

Расширенные настройки

Дополнительные настройки HMR см. в HMR API.

Бегать

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

 $ ./node_modules/.bin/webpack-dashboard -- webpack-dev-server

Поиск проблемы

HMR просто не применяет изменения

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

В Ubuntu вы можете запустить sysctl -a | grep inotify sysctl -a | grep inotify для просмотра текущего значения user.max_inotify_watches . Попробуйте увеличить это число, запустив: sudo sysctl fs.inotify.max_user_watches=524288 . Либо добавьте новую строку fs.inotify.max_user_watches=524288 в файл sudo vim /etc/sysctl.conf , а затем запустите sudo sysctl -p /etc/sysctl.conf , чтобы применить изменение.