Ответ 1
Прежде всего хочу отметить, что горячая замена модулей (HMR) все еще является экспериментальной функцией.
HMR - это способ обмена модулями в работающем приложении (и добавления/удаления модулей). Вы можете обновить измененные модули без полной перезагрузки страницы.
Документация
Предварительно требования:
- Использование плагинов: http://webpack.github.io/docs/using-plugins.html
- Разделение кода: http://webpack.github.io/docs/code-splitting.html
- webpack-dev-server: http://webpack.github.io/docs/webpack-dev-server.html
Это не так много для HMR, но вот ссылки:
- Пример: http://webpack.github.io/docs/hot-module-replacement-with-webpack.html
- API: http://webpack.github.io/docs/hot-module-replacement.html
Я добавлю эти ответы в документацию.
Как это работает?
Из представления приложения
Код приложения запрашивает во время выполнения HMR наличие обновлений. Среда выполнения HMR загружает обновления (асинхронные) и сообщает коду приложения, что обновление доступно. Код приложения запрашивает среду выполнения HMR о применении обновлений. Среда выполнения HMR применяет обновления (синхронизацию). Код приложения может или не может требовать взаимодействия с пользователем в этом процессе (вы решаете).
Из представления компилятора (веб-пакета)
В дополнение к обычным ресурсам компилятор должен выдавать "Обновление", чтобы разрешить обновление с предыдущей версии до этой версии. "Обновление" состоит из двух частей:
- манифест обновления (JSON)
- один или несколько блоков обновления (js)
Манифест содержит новый хэш компиляции и список всех блоков обновления (2).
Чанки обновления содержат код для всех обновленных модулей в этом чанке (или флаг, если модуль был удален).
Компилятор дополнительно удостоверяется, что идентификаторы модуля и чанка согласованы между этими сборками. Он использует JSON файл "records" для хранения их между сборками (или сохраняет их в памяти).
Из представления модуля
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?
Вот небольшой пример: http://webpack.github.io/docs/hot-module-replacement-with-webpack.html
Модуль может быть обновлен, только если вы "примете" его. Таким образом, вам нужно module.hot.accept
модуль у родителей или у родителей родителей... например, Маршрутизатор - это хорошее место или подпредставление.
Если вы хотите использовать его только с webpack-dev-server, просто добавьте webpack/hot/dev-server
качестве точки входа. В противном случае вам нужен код управления HMR, который вызывает check
и apply
.
Мнение: Что делает его таким крутым?
- Это LiveReload но для каждого вида модуля.
- Вы можете использовать его в производстве.
- Обновления относятся к разделению кода и загружают обновления только для использованных частей вашего приложения.
- Вы можете использовать его для части вашего приложения, и это не влияет на другие модули
- Если HMR отключен, весь код HMR удаляется компилятором (оберните его в
if(module.hot)
).
Предостережения
- Это экспериментально и не проверено так хорошо.
- Ожидайте некоторые ошибки.
- Теоретически может использоваться в производстве, но может быть слишком рано использовать его для чего-то серьезного.
- Идентификаторы модулей должны отслеживаться между компиляциями, поэтому вам необходимо хранить их (
records
). - Оптимизатор не может оптимизировать идентификаторы модулей после первой компиляции. Немного влияет на размер пакета.
- Код выполнения HMR увеличивает размер пакета.
- Для производственного использования требуется дополнительное тестирование для проверки обработчиков HMR. Это может быть довольно сложно.