Горячая замена модуля в 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, во время выполнения без необходимости полного обновления.
Вот как это работает внутри:
- Приложение просит среду выполнения HMR проверить наличие обновлений.
- Среда выполнения асинхронно загружает обновления и уведомляет приложение.
- Затем приложение просит среду выполнения применить обновления.
- Среда выполнения синхронно применяет обновления.
HMR повышает производительность при разработке приложения Redux. Redux — это контейнер с предсказуемым состоянием для приложений JavaScript. Это очень популярный современный фреймворк, основанный на React. Redux, по определению первого принципа Redux, представляет собой единственное хранилище общих данных, описанное в его документации как «Единый источник правды». Хранилище данных (простой объект JavaScript, обновляемый reducers
) будет обновляться по мере того, как пользователь работает с приложением. Каждая операция пользователя, такая как нажатие кнопки, загрузка внутренних данных и т. д., скорее всего, будет обновлять хранилище несколько раз. Нелегко исправить ошибку, когда ошибка возникает только с определенным снимком состояния.
HMR позволяет нам обновлять страницу без повторной инициализации глобального хранилища. Во время разработки Redux мы можем захотеть проверить хранилище после серии операций. Очень распространенный сценарий: ошибка возникает только после того, как мы добавили определенный (возможно, сложный) элемент в магазин. Без HMR мы должны сделать следующие шаги:
- Измените код, который потенциально вызывает ошибку.
- Обновите страницу, добавьте конкретный товар в магазин.
- Если ошибки сохраняются, повторите шаг 1.
Вышеупомянутая итерация будет повторяться снова и снова, если ошибку трудно найти. В реальном мире ошибка может появиться только после еще большего количества операций. HMR помогает нам скомпилировать и применить измененный код, сохраняя при этом текущее значение хранилища неизменным. Нам не нужно повторять Шаг 2. Это повышает эффективность разработки.
Функция в этом примере
Мы хотим, чтобы эта функция была минимальной, просто чтобы продемонстрировать возможности 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
, чтобы применить изменение.