Горячая замена модулей
Горячая замена модулей (HMR) обменивает, добавляет или удаляет модули во время работы приложения без полной перезагрузки. Это может значительно ускорить разработку несколькими способами:
- Сохраняет состояние приложения, которое теряется при полной перезагрузке.
- Экономит ценное время разработки, обновляя только изменённые части.
- Мгновенно обновляет браузер при внесении изменений в CSS/JS в исходном коде, что практически сравнимо с изменением стилей непосредственно в инструментах разработчика браузера.
Как это работает
Давайте пройдёмся по нескольким аспектам, чтобы понять, как именно работает HMR...
В приложении
Следующие шаги позволяют подменять модули в приложении:
- Приложение запрашивает у механизма HMR проверить наличие обновлений.
- Механизм асинхронно загружает обновления и уведомляет приложение.
- Приложение запрашивает у механизма HMR применить обновления.
- Механизм HMR синхронно применяет обновления.
Вы можете настроить HMR так, чтобы этот процесс происходил автоматически, или потребовать взаимодействия пользователя для применения обновлений.
В компиляторе
Помимо обычных ресурсов, компилятор должен сгенерировать «обновление», чтобы позволить обновление с предыдущей версии на новую. «Обновление» состоит из двух частей:
- Обновлённый манифест (JSON)
- Один или несколько обновлённых фрагментов (JavaScript)
Манифест содержит новый хеш компиляции и список всех обновлённых фрагментов. Каждый из этих фрагментов содержит новый код для всех обновлённых модулей (или флаг, указывающий на удаление модуля).
Компилятор гарантирует, что идентификаторы модулей и фрагментов согласованы между этими сборками. Обычно он сохраняет эти идентификаторы в памяти (например, с помощью webpack-dev-server), но также возможно их сохранение в файле JSON.
В модуле
HMR — это опциональная функция, которая затрагивает только модули, содержащие код HMR. Пример — исправление стилей через style-loader. Для работы исправления style-loader должен реализовывать интерфейс HMR; при получении обновления через HMR он заменяет старые стили новыми.
Аналогично, при реализации интерфейса HMR в модуле вы можете описать, что должно произойти при обновлении модуля. Однако в большинстве случаев писать код HMR в каждом модуле необязательно. Если модуль не имеет обработчиков HMR, обновление «поднимается» вверх. Это означает, что один обработчик может обновить целое дерево модулей. Если один модуль из дерева обновляется, вся совокупность зависимостей перегружается.
Подробную информацию об интерфейсе module.hot см. на странице API HMR.
В механизме выполнения
Здесь всё становится немного сложнее... Если вас не интересуют внутренности, смело переходите к странице API HMR или руководству по HMR.
Для механизма выполнения системы модулей генерируется дополнительный код для отслеживания parents и children модуля. С точки зрения управления, механизм выполнения поддерживает два метода: check и apply.
Механизм выполнения выполняет HTTP-запрос к манифесту обновления. Если запрос завершается ошибкой, обновления недоступны. Если запрос успешен, список обновлённых фрагментов сравнивается со списком загруженных фрагментов. Для каждого загруженного фрагмента загружается соответствующий фрагмент обновления. Все обновления модулей сохраняются в механизме выполнения. Когда все фрагменты обновления загружены и готовы к применению, механизм переходит в состояние ready.
Метод apply помечает все обновлённые модули как недействительные. Для каждого недействительного модуля должен быть обработчик обновления в модуле или его родительском модуле. В противном случае флаг недействительности поднимается вверх и делает родительские модули недействительными. Этот процесс повторяется до достижения точки входа приложения или модуля с обработчиком обновления (в зависимости от того, что произойдёт раньше). Если этот процесс поднимается до точки входа, процесс завершается ошибкой.
Затем все недействительные модули удаляются (через обработчик удаления) и разгружаются. Текущий хеш обновляется, и вызываются все обработчики accept. Механизм выполнения возвращается в состояние idle и всё продолжается как обычно.
Начало работы
HMR может использоваться в разработке как замена LiveReload. webpack-dev-server поддерживает режим hot, в котором он пытается обновить с помощью HMR, прежде чем пытаться перезагрузить всю страницу. Подробности см. в руководстве Горячая замена модулей.
Как и многие другие функции, мощь webpack заключается в его настраиваемости. Существует много способов конфигурирования HMR в зависимости от потребностей конкретного проекта. Однако для большинства целей
webpack-dev-server— хороший вариант, который быстро позволит вам начать работу с HMR.
© JS Foundation and other contributors
Licensed under the Creative Commons Attribution License 4.0.
https://v4.webpack.js.org/concepts/hot-module-replacement