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

245

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

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

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

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

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

Дан Абрамов
источник
HMR с Webpack почти так же хорош, как этот: medium.com/@the1mills/…
Александр Миллс

Ответы:

408

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

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

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

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

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

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

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

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

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

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

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

  1. манифест обновления (JSON)
  2. один или несколько блоков обновления (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. Это может быть довольно сложно.
Тобиас К.
источник
146
Один адский ответ.
Дан Абрамов
13
Еще раз спасибо за объяснение, я сделал видео, демонстрирующее возможности HMR для живого редактирования приложения React.
Дан Абрамов
1
довольно круто ... Я думал о создании реагирующего загрузчика, который добавляет HMR и асинхронную загрузку для реагирующих компонентов.
Тобиас К.
4
Я скопировал этот ответ в документацию: webpack.github.io/docs/hot-module-replacement-with-webpack.html
Тобиас К.
2
Вы можете отлавливать ошибки в обновленных модулях, когда requireпомещаете обработчик обновления HMR в блок try-catch.
Тобиас К.
10

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

Горячая замена модулей - одна из новейших технологий в разработке javascript, которая привлекает внимание разработчиков. Это помогает развитию, уменьшая количество обновлений страницы, заменяя модули изменениями во время выполнения.

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

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

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

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

  • Сохранить состояние приложения, которое потеряно при полной перезагрузке.

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

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

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

samuelj90
источник