Прежде всего хочу отметить, что горячая замена модулей (HMR) все еще является экспериментальной функцией.
HMR - это способ обмена модулями в работающем приложении (и добавления / удаления модулей). Вы можете обновить измененные модули без полной перезагрузки страницы.
Документация
Предварительно требования:
Это не так много для HMR, но вот ссылки:
Я добавлю эти ответы в документацию.
Как это работает?
Из представления приложения
Код приложения запрашивает среду выполнения HMR на наличие обновлений. Среда выполнения HMR загружает обновления (асинхронные) и сообщает коду приложения, что обновление доступно. Код приложения запрашивает среду выполнения HMR о применении обновлений. Среда выполнения HMR применяет обновления (синхронизацию). Код приложения может или не может требовать взаимодействия с пользователем в этом процессе (вы решаете).
Из представления компилятора (веб-пакета)
В дополнение к обычным ресурсам компилятор должен выдавать «Обновление», чтобы разрешить обновление с предыдущей версии до этой версии. «Обновление» состоит из двух частей:
- манифест обновления (JSON)
- один или несколько блоков обновления (js)
Манифест содержит новый хэш компиляции и список всех блоков обновления (2).
Блоки обновления содержат код для всех обновленных модулей в этом блоке (или флаг, если модуль был удален).
Компилятор дополнительно гарантирует, что идентификаторы модуля и чанка согласованы между этими сборками. Он использует JSON-файл «records» для хранения их между сборками (или сохраняет их в памяти).
Из представления модуля
HMR является опциональной функцией, поэтому она влияет только на модули, содержащие код HMR. Документация описывает API, который доступен в модулях. Обычно разработчик модуля записывает обработчики, которые вызываются при обновлении зависимости этого модуля. Они также могут написать обработчик, который вызывается при обновлении этого модуля.
В большинстве случаев не обязательно писать код HMR в каждом модуле. Если модуль не имеет обработчиков HMR, обновление всплывает. Это означает, что один обработчик может обрабатывать обновления для полного дерева модулей. Если один модуль в этом дереве обновляется, полное дерево модулей перезагружается (только перезагружается, а не переносится).
Из представления времени выполнения HMR (техническое)
Дополнительный код генерируется для времени выполнения модульной системы для отслеживания модуля parents
и children
.
На стороне управления среда выполнения поддерживает два метода: check
и apply
.
A check
выполняет HTTP-запрос к манифесту обновления. Когда этот запрос не выполняется, обновление недоступно. В противном случае список обновленных чанков сравнивается со списком загруженных в данный момент чанков. Для каждого загруженного блока загружается соответствующий блок обновления. Все обновления модуля хранятся во время выполнения как обновления. Среда выполнения переключается в ready
состояние, что означает, что обновление было загружено и готово к применению.
Для каждого нового запроса чанка в состоянии готовности также загружается чанк обновления.
В apply
флаги метод все обновленные модули недействительными. Для каждого недействительного модуля должен быть обработчик обновления в модуле или обработчики обновления в каждом родительском модуле. Еще недействительный всплывает и помечает всех родителей как недействительных тоже. Этот процесс продолжается до тех пор, пока не произойдет больше «пузыри». Если он всплывает до точки входа, процесс завершается неудачно.
Теперь все недействительные модули удалены (обработчик утилизации) и выгружены. Затем текущий хеш обновляется и вызываются все обработчики "accept". Среда выполнения переключается обратно в idle
состояние, и все продолжается как обычно.
Что я могу с этим сделать?
Вы можете использовать его в разработке в качестве замены LiveReload. На самом деле webpack-dev-server поддерживает горячий режим, который пытается обновить с помощью HMR, прежде чем пытаться перезагрузить всю страницу. Вам нужно только добавить webpack/hot/dev-server
точку входа и вызвать dev-сервер с помощью --hot
.
Вы также можете использовать его в производстве в качестве механизмов обновления. Здесь вам нужно написать собственный код управления, который интегрирует HMR с вашим приложением.
Некоторые загрузчики уже генерируют модули с возможностью горячего обновления. например, style-loader
может обмениваться таблицей стилей. Вам не нужно делать ничего особенного.
Предположим, я хочу обновить свои модули CSS (одна таблица стилей) и JS, когда я сохраняю их на диск, без перезагрузки страницы и без использования плагинов, таких как LiveReload. Может ли это помочь в замене горячего модуля?
да
Какую работу мне нужно делать, и что уже обеспечивает HMR?
Вот небольшой пример: https://webpack.js.org/guides/hot-module-replacement/
Модуль может быть обновлен, только если вы «примете» его. Таким образом, вам нужно module.hot.accept
модуль в родителей или родителей родителей ... например, Маршрутизатор это хорошее место, или подпредставление.
Если вы хотите использовать его только с webpack-dev-server, просто добавьте в webpack/hot/dev-server
качестве точки входа. В противном случае вам нужен код управления HMR, который вызывает check
и apply
.
Мнение: Что делает его таким крутым?
- Это LiveReload, но для каждого вида модуля.
- Вы можете использовать его в производстве.
- Обновления относятся к разделению кода и загружают обновления только для использованных частей вашего приложения.
- Вы можете использовать его для части вашего приложения, и это не влияет на другие модули
- Если HMR отключен, весь код HMR удаляется компилятором (оберните его
if(module.hot)
).
Предостережения
- Это экспериментально и не проверено так хорошо.
- Ожидайте некоторые ошибки.
- Теоретически может использоваться в производстве, но может быть слишком рано использовать его для чего-то серьезного.
- Идентификаторы модулей должны отслеживаться между компиляциями, поэтому вам необходимо их хранить (
records
).
- Оптимизатор больше не может оптимизировать идентификаторы модулей после первой компиляции. Немного влияет на размер пакета.
- Код выполнения HMR увеличивает размер пакета.
- Для производственного использования требуется дополнительное тестирование для проверки обработчиков HMR. Это может быть довольно сложно.