Mitril.js — это клиентский JavaScript-фреймворк (подобный React, Vue, Svelte и т.д.).
Мой текущий клиентский фреймворк — Svelte — просто великолепен. Единственный реальный недостаток заключается в том, что его нельзя использовать без инструментов сборки.
Поэтому, когда я заметил, что Mithril.js можно использовать без каких-либо инструментов сборки (простой ванильный JavaScript) И у него крошечное время выполнения (10 кБ) И у него есть реальные компоненты — я был заинтригован.
Наличие (реальных) компонентов отличает его от других фреймворков без сборки / с небольшим временем выполнения (таких как Alpine.js и Vue-Petite), потому что это позволяет создавать продвинутые полноразмерные SPA.
По сути, Mithril.js охватывает оба сценария — «прогрессивное улучшение» (как Alpine.js и Vue-Petite) и полноразмерный SPA (как React, Vue, Svelte).
Может ли это быть тем самым?
Единый инструмент для всего?
Святой Грааль?
Поэтому я поиграл с Mithil.js в выходные, чтобы посмотреть, что это такое.
С помощью Mithril.js вы генерируете HTML, используя диалект гиперскрипта, как показано ниже:
m("div", {style:"color:red"},
m("a", {href:"/page2"}, "click here"))
который генерирует
<div style="color:red">
<a href="/page2">click here</a>
</div>
В качестве альтернативы можно использовать синтаксис JSX (как в React), но тогда вам понадобятся инструменты build-tools.
Другим вариантом является использование библиотеки htm для генерации гиперскрипта — это позволит использовать литералы шаблонов JavaScript для стиля разработки, более близкого к JSX или HTML-шаблонам, используемым в Vue / Svelte.
Проблема в том, что шаблоны будут заново компилироваться (библиотекой htm) при каждом взаимодействии с приложением — что, как мне кажется, серьезно замедлит работу.
Поэтому, как мне кажется, оптимальным способом использования Mithril.js (без инструментов сборки) является написание кода в стиле hyperscript вручную — что на самом деле не так уж сложно, если привыкнуть.
Самая большая проблема — следить за закрывающими скобками при глубоко вложенных элементах.
Реактивность / обновления пользовательского интерфейса
В отличие от основных фреймворков (Reach, Vue, Svelte и т.д.) Mithril.js не обновляет пользовательский интерфейс в ответ на изменения состояния приложения / переменных.
Вместо этого он обновляет пользовательский интерфейс после обработки каждого события пользовательского интерфейса (или когда вы скажете ему об этом, вызвав m.redraw()
).
При каждом обновлении он перерисовывает все в новый виртуальный DOM, затем сравнивает его с предыдущей версией и, наконец, обновляет реальный DOM с учетом различий.
Это работает на удивление хорошо. Динамическое и автоматическое обновление пользовательского интерфейса — без какого-либо отслеживания состояния. Очень хорошо!
Тестовый проект
Недавно я создал небольшой SPA с Svelte здесь: https://simpledns.plus/dmarc-wizard (браузерный инструмент для генерации DMARC-записей — защиты электронной почты).
Чтобы опробовать Mithril.js, я повторно создал тот же SPA с использованием Mithril.js — см. https://simpledns.plus/dmarc-wizard-mithril (должно выглядеть и работать точно так же).
Исходный код JavaScript (который также является производственным кодом) доступен по адресу https://simpledns.plus/scripts/dmarc-wizard-mithril.js.
Вещи, которые мне действительно нравятся
-
Возможность охватить как сценарии «прогрессивного улучшения», так и полноразмерного SPA (см. выше).
-
Отсутствие необходимости/включения системы управления состоянием (см. выше).
-
Все, даже HTML, выражено на обычном JavaScript. Никакой «магии». Это значительно упрощает отладку в браузере, облегчает рефакторинг кода, снижает необходимость в расширениях VSCode и т.д.
-
Возможность использования крошечных функций рендеринга, для вещей, которые в Svelte потребовали бы отдельного компонента (и файла). Это поощряет и облегчает соблюдение принципа DRY (не повторяйся).
Вещи, которые действительно следует удалить
-
Mihtril.js (v. 2.0.4) включает обертку для ajax-вызовов на основе XHR. Они даже делают на этом акцент в самом первом предложении на сайте.
Это 2022 год — все браузеры теперь имеют
fetch
, и поддерживают async/await, что делаетfetch
простым в использовании.
Продвижение XHR как функции делает его довольно устаревшим.
И я бы предпочел иметь еще более компактный базовый фреймворк. -
Mithril.js также включает функцию маршрутизации, основанную на «хэш-банг URL» — тоже торговая точка в первом предложении на сайте.
Это, конечно, приятно иметь — но маршрутизация не нужна для сценариев прогрессивного улучшения (где я вижу потенциал Mithril.js), и разработчики могут предпочесть другие схемы маршрутизации (например, не хэшированные history-push/pop).
Поэтому, пожалуйста, уберите это или сделайте необязательным (сделав базовый фреймворк еще более компактным). -
Mithril.js включает полифилл для Promise.
Это 2022 год — все браузеры теперь поддерживают Promise.
Поэтому, пожалуйста, удалите это / сделайте необязательным (что сделает базовый фреймворк еще более компактным).
Заключение
Mithril.js имеет несколько действительно хороших и уникальных возможностей.
Но, хотя синтаксис гиперскрипта вполне применим для небольших виджетов, я бы не хотел использовать его в больших проектах.
Я просто не думаю, что синтаксис hyperscript настолько же читабелен, как, например, шаблоны Vue / Svelte (стандартный HTML с небольшим количеством дополнений).
А отслеживание этих закрывающих скобок/скобок с глубоко вложенными элементами просто сводило меня с ума.
Как сказано в документации по JSX (о чем-то другом, но с той же проблемой):
К сожалению, сбалансированные скобки не дают отличных синтаксических подсказок о том, где начинается и заканчивается элемент в больших деревьях. Сбалансированные именованные теги — важнейшая синтаксическая особенность нотации в стиле XML.
Поэтому, чтобы использовать Mithril.js, мне, вероятно, понадобится JSX, который требует инструментов сборки. И если мне все равно придется использовать инструменты сборки, то я все равно предпочту Svelte…