Вступление

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

Как это работает?

HMR - это способ обмена модулями в работающем приложении (и добавления / удаления модулей). Вы можете обновлять измененные модули без полной перезагрузки страницы.

Из представления приложения

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

Из представления компилятора webpack

В дополнение к обычным ресурсам компилятор должен выдать «Обновление», чтобы разрешить обновление с предыдущей версии до этой версии. «Обновление» состоит из двух частей:

  1. Обновить манифест (json)
  2. Один или несколько фрагментов обновления (js)

Манифест содержит новый хэш компиляции и список всех фрагментов обновления. Блоки обновления содержат код для всех обновленных модулей в этом блоке (или флаг, если модуль был удален). Компилятор дополнительно проверяет соответствие идентификаторов модулей и блоков между этими сборками. Он использует json-файл «записей» для их хранения между сборками (или сохраняет их в памяти).

Из представления модуля

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

Из представления среды выполнения HMR

Дополнительный код выдается для среды выполнения модульной системы для отслеживания модулей parents и children. Что касается управления, среда выполнения поддерживает два метода: check и apply.

check выполняет HTTP-запрос к манифесту обновления. Когда этот запрос не выполняется, обновление недоступно. В противном случае список обновленных фрагментов сравнивается со списком загруженных в данный момент фрагментов. Для каждого загруженного фрагмента загружается соответствующий фрагмент обновления. Все обновления модуля хранятся в среде выполнения как обновления. Среда выполнения переходит в состояние ready, что означает, что обновление было загружено и готово к применению.

Для каждого нового запроса фрагмента в состоянии готовности также загружается фрагмент обновления.

Метод apply помечает все обновленные модули как недопустимые. Для каждого недопустимого модуля должен быть обработчик обновлений в модуле или обработчики обновлений в каждом родительском элементе. В противном случае недопустимые пузыри всплывают и помечают всех родителей как недопустимые. Этот процесс продолжается до тех пор, пока «пузыри» не перестанут появляться. Если он поднимается до точки входа, процесс завершается ошибкой.

Теперь все недопустимые модули удалены (обработчик удаления) и выгружены. Затем текущий хеш обновляется и вызываются все обработчики «accept». Среда выполнения возвращается в состояние idle, и все продолжается как обычно.

Включение HMR в Angular

Чтобы HMR работал с Angular CLI, нам сначала нужно добавить новую среду и включить ее. Затем нам нужно обновить процесс начальной загрузки нашего приложения, чтобы включить модуль @ angularclass / hmr.

Добавить среду для HMR

Создайте файл с именем src/environments/environment.hmr.ts со следующим содержимым:

Обновите src/environments/environment.prod.ts и добавьте в среду флаг hmr: false:

Обновите src/environments/environment.ts и добавьте в среду флаг hmr: false:

Обновите angular.json, чтобы включить среду hmr, как объяснено здесь, и добавить конфигурации в сборку и использовать для включения hmr. Обратите внимание, что <project-name> здесь представляет имя проекта, в который вы добавляете эту конфигурацию в angular.json.

Добавьте необходимые типы в src/tsconfig.app.json

Запустите ng serve с флагом --configuration hmr, чтобы включить hmr, и выберите новую среду: $ ng serve --configuration hmr

Создайте для этого ярлык, обновив package.json и добавив запись в объект скрипта:

"scripts": {
  ...
  "hmr": "ng serve --configuration hmr"
}

Добавить зависимость для @ angularclass / hmr и настроить приложение

Чтобы HMR заработал, нам нужно установить зависимость и настроить наше приложение для ее использования. Установите модуль @angularclass/hmr как зависимость от разработчика: $ npm install @angularclass/hmr --save-dev

Создайте файл с именем src/hmr.ts со следующим содержимым:

Обновите src/main.ts, чтобы использовать только что созданный файл:

Запуск среды разработки с включенной HMR

Теперь, когда все настроено, мы можем запустить новую конфигурацию:

$ npm run hmr

Проблема

На самом деле в Angular нет настоящей горячей перезагрузки. Это казалось многообещающим, но после простого теста оказалось, что настоящая горячая перезагрузка модуля не выполняется.

По умолчанию HMR автоматически теряет состояние, независимо от того, какой фреймворк вы используете, если только вы не используете что-то вроде состояния Redux. Так что да, это поведение по умолчанию, не беспокойтесь!

Сохранить состояние при горячей перезагрузке

Чтобы HMR работал так, как нужно, наша команда разработала плагин. На сегодняшний день плагин находится в бета-версии, поэтому вы можете установить его следующим образом:

$ npm install @ngxs/hmr-plugin --save-dev

Официальный релиз запланирован на версию 3.4.0.

Что дальше

Вам просто нужно сделать следующее: удалить файл hmr.ts и обновить main.ts:

Наслаждайтесь своим HMR с NGXS

Как это работает?

Жизненный цикл NGXS HMR

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