Server-Side Rendering (SSR) в Mithril позволяет рендерить компоненты на сервере, возвращая готовый HTML-код клиенту. Это ускоряет время загрузки страницы и улучшает SEO, сохраняя при этом реактивность приложения после инициализации на клиенте. Основные этапы настройки SSR в Mithril включают конфигурацию серверной среды, подготовку компонентов для рендеринга и интеграцию с клиентским кодом.
Mithril может использоваться в Node.js без каких-либо модификаций.
Для SSR достаточно установить пакет mithril:
npm install mithril
После установки в Node.js импортируется модуль:
const m = require('mithril');
Для поддержки JSX можно подключить Babel и соответствующие пресеты,
но стандартный синтаксис m() является достаточным для
большинства сценариев SSR.
Метод m.render() позволяет генерировать HTML-строку на
сервере. В отличие от клиентского рендеринга, где m.mount()
связывает DOM с компонентом, на сервере создаётся чистый HTML.
Пример серверного рендеринга:
const m = require('mithril');
const App = {
view: () => m("div", [
m("h1", "Привет, Mithril SSR!"),
m("p", "Это пример серверного рендеринга.")
])
};
const html = m.render({}, m(App));
console.log(html);
В результате html будет содержать:
<div><h1>Привет, Mithril SSR!</h1><p>Это пример серверного рендеринга.</p></div>
Параметр {} в m.render() передаёт объект
DOM для монтирования, но при SSR он может быть пустым, так как результат
нужен как строка.
Для отдачи страниц с SSR часто используется Express:
const express = require('express');
const m = require('mithril');
const App = {
view: () => m("div", [
m("h1", "Mithril + SSR"),
m("p", "Страница рендерится на сервере.")
])
};
const server = express();
server.get('/', (req, res) => {
const html = m.render({}, m(App));
res.send(`
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<title>Mithril SSR</title>
</head>
<body>
${html}
<script src="/bundle.js"></script>
</body>
</html>
`);
});
server.listen(3000, () => console.log('Сервер запущен на http://localhost:3000'));
В этом примере компонент App рендерится на сервере, а
клиентский JavaScript (например, собранный через Webpack) подключается
для дальнейшей реактивности.
Некоторые компоненты могут использовать клиентские API, недоступные
на сервере, например window, document или
таймеры. Для SSR необходимо условно проверять наличие этих объектов:
const TimerComponent = {
oninit: vnode => {
if (typeof window !== "undefined") {
vnode.state.time = 0;
vnode.state.interval = setInterval(() => {
vnode.state.time++;
m.redraw();
}, 1000);
}
},
onremove: vnode => {
if (vnode.state.interval) clearInterval(vnode.state.interval);
},
view: vnode => m("div", `Время: ${vnode.state.time || 0}`)
};
Использование typeof window !== "undefined" позволяет
безопасно рендерить компонент на сервере.
После отдачи HTML с сервера клиент должен взять на себя управление
DOM. В Mithril это делается с помощью m.mount() или
m.startComputation()/m.endComputation().
Основной подход — монтировать тот же компонент на тот же корневой
элемент:
const m = require('mithril');
const App = require('./App');
document.addEventListener("DOMContentLoaded", () => {
m.mount(document.body, App);
});
При этом Mithril автоматически применяет diff и делает DOM реактивным, без полного перерисовывания страницы.
require.m.render() можно кэшировать и отдавать
повторно.window или document, должен
быть изолирован через проверки.SSR-окружение легко интегрируется с Webpack или Vite:
node.<script>.Пример конфигурации Webpack для серверного бандла:
module.exports = {
target: 'node',
entry: './server.js',
output: {
filename: 'server.bundle.js',
path: __dirname + '/dist'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: 'babel-loader'
}
]
}
};
Такой подход позволяет создавать изолированное SSR-окружение с полным контролем над серверным и клиентским кодом.
Mithril имеет встроенный роутер, который может использоваться и на сервере:
const m = require('mithril');
const Home = { view: () => m("h1", "Главная") };
const About = { view: () => m("h1", "О сайте") };
const routes = {
"/": Home,
"/about": About
};
function renderRoute(url) {
const component = routes[url] || { view: () => m("h1", "404") };
return m.render({}, m(component));
}
При SSR маршруты выбираются на основе запроса и рендерятся соответствующие компоненты, что обеспечивает корректную отдачу HTML для каждой страницы.
Этот подход формирует полностью функциональное SSR-окружение в Mithril с серверным рендерингом, гидратацией клиентской части, маршрутизацией и возможностью масштабирования приложений.