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

Доступные инструменты

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

Чтобы понять роль этих инструментов и то, как они должны быть настроены в нашем приложении, я считаю важным понять, как работает горячая перезагрузка. Решение с webpack называется горячей заменой модуля (HMR).

Как работает Webpack HMR

График из статьи Raja Rao DV действительно помогает понять весь процесс более подробно. На высоком уровне в HMR есть четыре фазы:

  1. Создание горячих фрагментов. При изменении файла должны быть сгенерированы горячие фрагменты, содержащие измененную часть.
  2. Подавать горячими кусочками. Сгенерированные фрагменты должны обслуживаться каким-либо сервером.
  3. Доставай горячие куски. Веб-страница в браузере должна быть подключена к серверу через WebSocket, чтобы он мог получать уведомления о наличии новых горячих блоков. Затем клиент извлекает фрагменты.
  4. Реализуйте горячие фрагменты. Затем клиентская сторона должна решить, что делать с фрагментами обновления.

Инструменты настройки для webpack HMR

  1. Создание горячих фрагментов. webpack и webpack.HotModuleReplacementPlugin генерируют горячие фрагменты. Итак, в webpack.config.js нам нужно добавить:

2. Подавать горячими кусочками. webpack-dev-server — это готовое решение для обслуживания файлов, выпущенных из веб-пакета. Это сервер экспресс-узла, использующий webpack-dev-middleware под капотом. Вы можете запустить его через CLI напрямую

Здесь опция --hot на самом деле говорит webpack-dev-server подавать горячие порции. Опция --inline на самом деле выполняет третий шаг: вводит код в клиент, чтобы оставаться на связи и получать горячие фрагменты.

Также можно настроить через webpack.config.js

Подробнее об использовании webpack-dev-server можно прочитать здесь.

Однако webpack-dev-server становится сложнее, когда у вас есть собственный сервер узла для вашего веб-приложения. В этом случае вам нужно запустить два сервера, а прокси-апи вызывает webpack-dev-server к вашему собственному серверу узла (подробнее см. Это).

Альтернативой является использование webpack-dev-middleware непосредственно на вашем сервере узла. Это использует ваш существующий сервер узла для обслуживания файлов, выпущенных из webpack. Вам также нужно webpack-hot-middleware, чтобы включить горячую перезагрузку. Просто используйте их как обычное промежуточное ПО:

3. Доставайте горячие куски. Нам нужно внедрить клиентский код веб-сокета в приложение. С решением webpack-dev-server CLI нам не нужно ничего делать. Опция --inline уже помогает вводить код. Если настраивается через webpack.config.js, добавляем в конфигурационный файл:

С раствором webpack-dev-middleware и webpack-hot-middleware добавьте его к webpack.config.js

4. Реализуйте горячие фрагменты. На данный момент клиент фактически уже получает новые фрагменты кода благодаря замечательному веб-пакету. Что делать с новыми чанками, на самом деле выходит за рамки webpack. Webpack HMR имеет API module.hot.accept(“./someFileName”, callbackToRunWhenThatFileIsRecompiled), который обеспечивает обратный вызов разработчикам после принятия файла обновления. Мы можем вручную реализовать эти обратные вызовы или использовать некоторые существующие инструменты. Например, style-loader реализует этот API внутри и, таким образом, разрешает горячую перезагрузку css. Усилия вроде react-hot-loader и react-transform делают одно и то же, пытаясь перезагрузить реагирующие компоненты в горячем режиме. Это просто становится более сложным при попытке сохранить состояние реактивного компонента.

Дэн Абрамов хорошо объясняет проблемы с горячей перезагрузкой реакции в своей статье. На самом деле мы можем реализовать горячие чанки без каких-либо инструментов:

И мы можем реализовать горячие чанки для редукции с помощью простого веб-пакета HMR:

Это заменит избыточность (без изменения состояния хранилища) и повторно отобразит корневой компонент (таким образом, все компоненты, которые он включает). См. больше обсуждений использования vanilla HMR API здесь.

Однако проблема в том, что NextApp на самом деле не тот же компонент, что и App; поэтому всякий раз, когда код изменяется, react размонтирует старый компонент. Это приводит к потере внутреннего состояния компонента (хотя состояние внешнего хранилища сохраняется).

react-hot-loader и react-transform — две разные попытки Дэна Абрамова. Каждый решает разные проблемы, но ни один из них не идеален. Предстоящий react-hot-loader v3 выглядит многообещающе и призван заменить два других. В настоящее время он находится в стадии бета-тестирования. Чтобы использовать react-hot-loader v3, следуйте их инструкции. Я также ссылаюсь на это при реализации обратного вызова module.hot.accept.

Резюме

Таким образом, вот как выглядит моя конфигурация для включения горячей перезагрузки.

Конфигурация веб-пакета:

Смонтируйте промежуточное ПО webpack для обслуживания горячих блоков:

И, наконец, реализовать горячую перезагрузку для реакции:

Конфигурация Babel (требуется для react-hot-loader v3)