Hyperapp — это минималистичный JavaScript-фреймворк, ориентированный на создание интерфейсов с декларативным подходом и реактивным обновлением состояния. Несмотря на малый размер, он полностью совместим с современными инструментами разработки, включая горячую перезагрузку (hot module replacement, HMR) и live-reload, что значительно ускоряет процесс разработки и тестирования интерфейсов.
Горячая перезагрузка позволяет обновлять состояние и компоненты приложения без полной перезагрузки страницы. В контексте Hyperapp это означает:
Главная цель HMR — ускорение цикла «изменение → просмотр результата», исключая необходимость сброса состояния приложения или повторного рендеринга всех компонентов.
Live-reload отличается от HMR тем, что при изменениях страница полностью перезагружается. В Hyperapp это особенно полезно для простых проектов или когда нет сложного состояния, требующего сохранения. Настройка обычно осуществляется через сборщики типа Vite, Webpack или Parcel.
Пример настройки с Vite:
import { app } from "hyperapp";
import { view } from "./view";
import { state, actions } from "./store";
const main = app({
init: state,
view,
node: document.getElementById("app"),
actions
});
if (import.meta.hot) {
import.meta.hot.accept((newModule) => {
main.replaceView(newModule.view);
});
}
В данном примере:
import.meta.hot.accept отслеживает изменения в модуле
view.main.replaceView подставляет обновлённый компонент без
сброса состояния.Hyperapp использует чистые функции для описания действий (actions) и состояния (state). Это позволяет безопасно заменять их во время разработки.
Пример HMR для store:
if (import.meta.hot) {
import.meta.hot.accept("./store", (newModule) => {
main.replaceState(newModule.state);
main.replaceActions(newModule.actions);
});
}
Ключевые моменты:
replaceState подменяет текущее состояние на новое, не
пересоздавая приложение.replaceActions обновляет действия, чтобы новые функции
могли применяться сразу.В Hyperapp компоненты — это функции, возвращающие виртуальные DOM-узлы. HMR позволяет заменить их на лету, сохраняя состояние родительских компонентов:
import { h } from "hyperapp";
import { Child } from "./Child";
export const view = (state, actions) => (
h("div", {}, [
h("h1", {}, "Главный компонент"),
h(Child, { data: state.data })
])
);
if (import.meta.hot) {
import.meta.hot.accept("./Child", (newModule) => {
main.replaceView(() => view);
});
}
Преимущества:
Child применяются без полной
перезагрузки.Для Webpack необходимо использовать webpack-dev-server с включённым HMR:
module.exports = {
entry: "./src/index.js",
mode: "development",
devServer: {
hot: true,
open: true
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: "babel-loader"
}
]
}
};
После этого достаточно подключить HMR в коде приложения:
if (module.hot) {
module.hot.accept("./view", () => {
main.replaceView(require("./view").view);
});
}
| Параметр | HMR | Live-reload |
|---|---|---|
| Состояние сохраняется | Да | Нет |
| Полная перезагрузка страницы | Нет | Да |
| Применение изменений в компоненте | Немедленно | После перезагрузки |
| Использование в Hyperapp | Предпочтительно для крупных приложений | Удобно для прототипов |
Горячая перезагрузка и live-reload делают Hyperapp удобным не только для небольших прототипов, но и для серьёзных SPA, ускоряя разработку и снижая вероятность ошибок при частых правках кода.