Hot Module Replacement (HMR) — механизм обновления модулей приложения без полной перезагрузки страницы. В контексте Riot.js HMR позволяет заменять теги, логику и стили на лету, сохраняя состояние приложения и DOM. Это критически важно при разработке сложных интерфейсов, где постоянный reload приводит к потере данных, сбросу состояния и замедлению итераций.
Live reload — более простой механизм, при котором при изменении файлов страница автоматически перезагружается целиком. В Riot.js оба подхода могут использоваться совместно, но HMR даёт качественно иной уровень удобства.
Riot.js основан на компонентной модели, где каждый тег (tag) представляет собой комбинацию:
Такое разделение позволяет относительно просто внедрять HMR на уровне отдельных тегов. Однако Riot.js не содержит встроенной реализации HMR — она обеспечивается через инструменты сборки и dev-серверы.
Ключевая особенность: тег Riot.js компилируется в JavaScript-функцию, которая регистрируется в runtime. HMR должен уметь:
Live reload реализуется через файловый watcher и WebSocket-соединение между dev-сервером и браузером.
Типовой процесс:
.riot, .js,
.css)Для Riot.js live reload работает без дополнительных адаптаций, так как перезагрузка страницы не требует поддержки со стороны фреймворка.
Эти ограничения становятся критичными при росте проекта.
HMR работает на уровне модулей JavaScript. Вместо перезагрузки страницы:
Для Riot.js это означает обновление:
.riot-файла пересобирается
соответствующий модульwebpack-dev-serverriot-loadermodule.hotПример конфигурации загрузчика:
{
test: /\.riot$/,
use: [
{
loader: 'riot-loader',
options: {
hot: true
}
}
]
}
Скомпилированный тег получает доступ к module.hot, через
который можно:
Типовая логика:
riot.registryVite обеспечивает HMR из коробки благодаря ES-модулям и WebSocket-каналу. Для Riot.js используется плагин:
@riotjs/vite-plugin-riotОсобенности:
Vite передаёт обновления как ESM, что упрощает повторную регистрацию тегов и снижает накладные расходы.
Ключевая задача HMR — не потерять состояние.
Подходы:
statedisposeПример:
if (import.meta.hot) {
import.meta.hot.dispose(data => {
data.state = this.state
})
import.meta.hot.accept(() => {
this.state = import.meta.hot.data.state
})
}
Такой подход особенно эффективен при использовании внешних хранилищ состояния.
Riot.js поддерживает scoped CSS внутри тегов. HMR может обновлять стили:
Это достигается за счёт:
<style>-узловДублирование тегов Возникает при повторной регистрации без очистки старой версии.
Потеря событий Обработчики событий могут быть привязаны к устаревшим функциям.
Утечки памяти Старые инстансы остаются в памяти при некорректной утилизации.
Несовместимость плагинов Некоторые плагины Riot.js не рассчитаны на повторную инициализацию.
mountHMR позволяет:
Это особенно ценно при разработке сложных UI с вложенными тегами и динамической разметкой.
| Характеристика | Live reload | HMR |
|---|---|---|
| Перезагрузка страницы | Да | Нет |
| Сохранение состояния | Нет | Да |
| Скорость итераций | Средняя | Высокая |
| Сложность настройки | Минимальная | Средняя |
| Поддержка Riot.js | Автоматическая | Через сборщик |
В больших Riot.js-приложениях HMR становится не просто удобством, а необходимым инструментом:
Live reload остаётся полезным на ранних этапах или в простых проектах, но при масштабировании уступает HMR по всем ключевым параметрам.