Mithril — это современный клиентский JavaScript-фреймворк, ориентированный на создание быстрых и лёгких веб-приложений. Его ключевое отличие от других фреймворков заключается в минимальном объёме и высокой производительности. Архитектура приложений на Mithril базируется на компонентах и виртуальном DOM, что позволяет эффективно управлять состоянием интерфейса и обновлять только изменившиеся элементы.
Компоненты — основной строительный блок
Mithril-приложений. Каждый компонент — это объект с методом
view, который возвращает описание UI в виде виртуальных
узлов. Компоненты могут содержать локальное состояние и методы
жизненного цикла (oninit, oncreate,
onupdate, onremove).
const MyComponent = {
oninit(vnode) {
vnode.state.counter = 0;
},
view(vnode) {
return m("button", {
onclick: () => vnode.state.counter++
}, `Нажато ${vnode.state.counter} раз`);
}
};
Структура проекта на Mithril обычно минимальна: один основной файл входа, папка компонентов и, при необходимости, папка для моделей данных и утилит. Это упрощает работу с микрофронтендами, так как каждый микрокомпонент может быть автономным и подключаться к основной системе через стандартный интерфейс.
Микрофронтенд — это автономный модуль интерфейса, который можно интегрировать в более крупное приложение без конфликта с другими частями системы. Mithril благодаря лёгкости и простоте API идеально подходит для реализации микрофронтендов.
Ключевые аспекты при разработке микрофронтендов с Mithril:
m.request и виртуальный DOM делают
интеграцию лёгкой и автономной.Пример микрофронтенда с локальным маршрутом:
const MicroApp = {
oninit(vnode) {
vnode.state.page = "home";
},
view(vnode) {
return m("div", [
m("nav", [
m("button", {onclick: () => vnode.state.page = "home"}, "Главная"),
m("button", {onclick: () => vnode.state.page = "about"}, "О нас")
]),
vnode.state.page === "home" ? m("div", "Контент главной") : m("div", "Контент о нас")
]);
}
};
m.mount(document.getElementById("micro-root"), MicroApp);
При объединении нескольких микрофронтендов важно наладить обмен данными между ними. Mithril предоставляет несколько подходов:
Глобальное состояние через простой объект:
const store = { user: null };
Каждый микрофронтенд может читать и изменять это состояние, сохраняя при этом изоляцию компонентов.
Событийная шина: реализация через простой pub/sub:
const EventBus = {
events: {},
emit(event, data) {
(this.events[event] || []).forEach(fn => fn(data));
},
on(event, fn) {
this.events[event] = this.events[event] || [];
this.events[event].push(fn);
}
};
EventBus.on("userUpdated", data => console.log("Пользователь обновлён", data));
EventBus.emit("userUpdated", { name: "Alice" });Передача свойств через vnode.attrs:
при монтировании одного компонента в другой можно передать данные
напрямую.
Mithril поддерживает работу с асинхронными запросами через функцию
m.request. Это позволяет микрофронтендам загружать данные
независимо от основной части приложения:
const DataComponent = {
oninit(vnode) {
vnode.state.items = [];
m.request({ method: "GET", url: "/api/items" })
.then(result => vnode.state.items = result);
},
view(vnode) {
return m("ul", vnode.state.items.map(item => m("li", item.name)));
}
};
Важно помнить, что m.request возвращает промис, и
Mithril автоматически инициирует перерисовку после изменения
состояния.
Mithril разработан с акцентом на производительность. При работе с микрофронтендами важно соблюдать несколько правил:
key для списков элементов, чтобы
виртуальный DOM мог эффективно определять изменения.m("ul", items.map(item => m("li", { key: item.id }, item.name)));
Mithril можно использовать совместно с другими микрофронтенд-стеками, так как его API компактно и не конфликтует с внешними библиотеками. В больших системах можно:
import() и монтировать их в определённые контейнеры
DOM.Понимание жизненного цикла компонентов Mithril критично при проектировании микрофронтендов:
oninit(vnode) — инициализация состояния и привязка
данных.oncreate(vnode) — доступ к DOM после монтирования.onupdate(vnode) — вызов при обновлении DOM.onremove(vnode) — освобождение ресурсов и очистка
слушателей.Эти методы позволяют создавать сложные микрофронтенды с асинхронной загрузкой данных, анимациями и интеграцией с внешними библиотеками.
const ComplexMicroApp = {
oninit(vnode) {
vnode.state.items = [];
vnode.state.loading = true;
m.request({ method: "GET", url: "/api/items" })
.then(result => {
vnode.state.items = result;
vnode.state.loading = false;
});
},
view(vnode) {
return m("div", [
vnode.state.loading ? m("p", "Загрузка...") :
m("ul", vnode.state.items.map(item => m("li", { key: item.id }, item.name))),
m("button", { onclick: () => console.log("Действие кнопки") }, "Кнопка действия")
]);
}
};
m.mount(document.getElementById("micro-root"), ComplexMicroApp);
Такой подход обеспечивает автономность микрофронтенда, поддерживает асинхронную загрузку данных, обработку событий и лёгкую интеграцию в крупные системы.