Что такое горячая замена модуля в Webpack?

Я прочитал несколько страницы о горячей замене модуля в Webpack.
Там даже образец приложения, использует его.

Я прочитал все это и до сих пор не понимаю.

Что я могу с этим сделать?

  1. Предполагается, что он будет использоваться только в разработке, а не в производстве?
  2. Это как LiveReload, но надо же самому управлять?
  3. WebpackDevServer каким-либо образом интегрирован с LiveReload?

Предположим, я хочу обновить свои модули CSS (одна таблица стилей) и JS при сохранении их на диск, не перезагружая страницу и не используя такие плагины, как LiveReload. Может ли мне помочь замена горячего модуля? Какую работу мне нужно выполнять и что уже предоставляет HMR?


person Dan Abramov    schedule 05.07.2014    source источник
comment
HMR с Webpack почти так же хорош, как этот: medium.com/@ the1mills /   -  person Alexander Mills    schedule 19.09.2015


Ответы (2)


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

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

Документация

Предварительно требования:

Это не так уж и много для HMR, но вот ссылки:

Я добавлю эти ответы в документацию.

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

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

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

Из представления компилятора (веб-пакета)

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

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

Манифест содержит новый хэш компиляции и список всех блоков обновления (2).

Блоки обновления содержат код для всех обновленных модулей в этом блоке (или флаг, если модуль был удален).

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

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

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

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

Из представления среды выполнения HMR (технический)

Дополнительный код излучается для среды выполнения модульной системы для отслеживания модулей parents и children.

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

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. Это может быть довольно сложно.
person Tobias K.    schedule 05.07.2014
comment
Чертовски ответ. - person Dan Abramov; 05.07.2014
comment
Еще раз спасибо за объяснение. Я снял видео, демонстрирующее возможности HMR для редактирования видео в реальном времени. Приложение React. - person Dan Abramov; 06.07.2014
comment
довольно круто ... Я думал о создании загрузчика реакции, который добавляет HMR и асинхронную загрузку для реагирующих компонентов. - person Tobias K.; 07.07.2014
comment
Я скопировал этот ответ в документацию: webpack.github.io/ docs / hot-module-replacement-with-webpack.html - person Tobias K.; 07.07.2014
comment
@TobiasK. У меня вопрос - как React Hot Loader и другие предотвращают сбой браузера, если вы загружаете новый файл с синтаксическими ошибками? Горячая перезагрузка менее полезна, если вы аварийно завершаете работу браузера при внесении изменений, потому что тогда вам придется обновиться для восстановления, что противоречит цели. - person Alexander Mills; 04.09.2015
comment
Вы можете поймать ошибки в обновленных модулях, если заключите require в обработчике обновления HMR в блок try-catch. - person Tobias K.; 04.09.2015
comment
Это кажется отличным ответом, но я заблудился! Что такое модуль реагирующий компонент? Если да, то они для меня обновлялись с живой перезагрузкой с помощью таких инструментов, как gulp. Мне нужен обычный учебник для разработчиков. Я единственный разработчик, который этого не понял ... - person landed; 09.05.2016
comment
@TobiasK. здесь, в статье, под модулем вы подразумеваете модуль commonjs? Кроме того, chunk - это набор модулей commonjs, объединенных вместе? - person SuperManEver; 25.10.2017
comment
В документации указано: HMR is not intended for use in production, meaning it should only be used in development. - person danilo; 01.07.2020

Хотя принятый ответ объясняет все правильно, следующее описание должно помочь быстрее понять, что такое HMR.

По сути (в двух словах!) - он помогает разработке, уменьшая количество обновлений страниц за счет замены модулей изменениями во время выполнения.

Во время поиска по HMR я нашел статью, в которой объясняется концептуальная ошибка. довольно длинный, поэтому вот изображение в формате GIF, которое без лишних слов объясняет концепцию.

Вот он в работе - обратите внимание, что таймер не сбрасывается на 0, как это было бы после перезагрузки страницы, и css также меняет автоматическое обновление. Горячая замена модуля GIF

Webpack помогает достичь HMR. Вы можете найти документы здесь

Это помогает добиться следующего:

  • Сохранять состояние приложения во время перезагрузки (которое всегда теряется без HMR)

  • Экономьте драгоценное время разработки, обновляя только то, что изменилось.

  • Настраивайте стили быстрее - почти сравнимо с изменением стилей в отладчике браузера.

Вот руководство по веб-пакету для достижения HMR

person samuelj90    schedule 18.09.2017
comment
Какой потрясающий, простой и прямой ответ, подарок лучше объясняет 1000 слов - person danilo; 01.07.2020