Comments 23
Можете, пожалуйста, объяснить зачем вообще нужен htmx? Мы все последние 20 лет вешали атрибуты на элементы и обрабатывали их через жс (можно даже было собрать это в 1 файл и сказать что это библиотека), но потом пришло понимание что хтмл просто не очень хорошо подходит для шаблонизации и в целом для описания императивной логики, которая в любом случае всегда нужна в реальной жизни. К тому же в HTMX все равно есть идиоматические способы писать вещи на жс. А для чего это все тогда?
Для сокращения размеров файлов, скачиваемых на клиенте. От этого всё идёт. Условно, скачать 1 мб HTML и потом 20 мб с css и html с сервера быстрее, чем 21 мб сразу качать.
Но, есть много ньюансов с кешированием, клиентскими данными, быстротой разработки и другим. Это просто быстрый ответ на вопрос.
HTMX — это попытка (и достаточно успешная на мой взгляд) привнести новый подход к разработке веб-приложений, ориентированый на серверный рендеринг, с добавлением некоторых недостающих вещей в HTML.
Идея в том, чтобы дать браузерам выдохнуть и не перемалывать мегабайты JavaScript на устройствах пользователей, чтобы отрисовать интерфейс. Вместе с этим уйти от издержек, которые приносят современные JavaScript-комбайны.
Вместо этого пусть браузеры делают то, что было заложено в них при создании — слать HTTP-запросы к серверу, получать в ответ HTML и рендерить его. А браузеры делают это чертовски хорошо и быстро. И пусть логика отрисовки и работы с данными будет на сервере, где ей и место. А тонкая библиотека JavaScript будет инициировать нужные HTTP-запросы и вставлять результат в нужные места документа.
Подход не новый, так делали деды ещё до появления всяких React-ов. HTMX просто предложил простой и декларативный синтаксис плюс старый советский рендеринг на сервере. И простота этого подкупила, особенно на фоне оверинжиниринга в современном фронтенде. А дополнительная популярность возникла из-за забавных мемов и специфической "рекламной кампании", если это можно так назвать.
очередная замена "ххх", который сам является заменой "yyy"
Мне кажется, автор не понимает, зачем и как использовать htmx. И примеры некорректны.
Первый пример на vue показывает инкремент на клиенте. Про HMPL не скажу, но htmx подразумевает обновление на бэке. При этом не понятно, зачем hx-get="/api/clicks"
на div
- какое действие должно триггернуть это?
Во втором примере - тоже не верное использование. Опять непонятный hx-get="/api/registeredEmail"
на span, который так же ничем не будет вызван. Еще и onsubmit="function prevent(e){e.preventDefault();};return prevent(event);" id="form">
зачем-то.
Первый пример должен быть примерно таким:
<div>
<button hx-post="/api/increment" hx-target="#counter" hx-swap="outerHTML">Click!</button>
<div id="counter">Clicks: 0</div>
</div>
и в зависимости от ответа бэка на такой запрос может меняться hx-swap
- outerHTML
, если возвращается <div id="counter">Clicks: {{count}}</div>
, либо innerHTML
если бэк отвечает просто Clicks: {{count}}
Второй пример должен быть таким:
<script src="/path/to/htmx.min.js"></script>
<div>
<form hx-post="/api/register" hx-target="#notification" hx-swap="outerHTML">
<div class="form-row">
<label for="name">Enter your email: </label>
<input type="text" name="email" id="email" required />
</div>
<div class="form-row">
<input type="submit" value="Register!" />
</div>
</form>
<p id="notification"></p>
</div>
И бэк должен ответить <p id="notification">Email {{ email }} successfully registered!</p>
.
Смысл HTMX мне видится не в замене реактивных клиентских фреймворков (про сравнение с vue), а упрощение SSR (возврат к концепции, когда все рендерится на бэке), упрощении взаимодействия бэка и фронта и добавлении интерактивности. Понятно, что какой-нибудь draw.io не сделаешь на HTMX, но для какого-нибудь не сильно сложного сайта (тот же хабр) зачем тянуть какой-нибудь frontend framework или библиокету?
Поправил примеры с HTMX - спасибо! По поводу того, что не знаю, зачем HTMX использовать, может оно и так. Если работать с сервером, то иногда требуются дополнительные настройки, современные функци, идующие с fetch, и ещё плюшки работы с javascript и DOM деревом. HTMX упрощает в этом смысле работу с сервером, что всего по минимуму, но на практике, когда хочется чего-то большего, то библиотека выдаёт свой потолок вот этими упрощениями.
Если работать с сервером, то иногда требуются дополнительные настройки, современные функци, идующие с fetch, и ещё плюшки работы с javascript и DOM деревом
Например?
Я не говорю, что HTMX должен заменить библиотеки и фреймворки. Я считаю, что разные инструменты нужны для разных вещей. Для минимального манипулирования DOM яв предпочитаю использовать hyperscript (от автора HTMX и неплохой интеграции с ним) или alpineJS.
Текущий подход с отдельным бэком и фронтом на React/Vue/Angular/Svelte/etc... позволяет более гибко управлять командами, разделяя ответственность, строя независимые циклы релизов и прочее. Но у этого есть цена - переусложнение (отдельный пайплайн сборки фронта, отдельные настройки для SSR, backend-for-frontend простихоспади), проблема синхронизации и передачи состояний (раньше состояние хранилось и управлялось на бэке). И некоторые функции в текущих фреймворках выглядят как решения проблем, которые были искусственно созданы. Ну и порой неадекватный размер фронтовых бандлов - туда же.
Для того, чтобы отобразить просто список статей/статью, табличку, обработать форму - вовсе не обязательно строить второе приложение.
Это, само собой, не касается приложений, которые полностью работают на фронте (тот же draw.io, google docs, всякие игры и прочее).
Если правильно разбить html на бэке (на переиспользуемые компоненты) - работа с htmx не доставляет головной боли=)
При этом, в случае с HMPL - если я правильно понял, это все равно отдельный JS файл (или файлы), который с нуля строит страницу. Концептуально, он выглядит более похожим на фреймворки большой тройки. И получается вообще все будет в бандле, даже элементы страниц, которые на данный момент не нужны. Понятно, что можно как-то настроить бандлер и подгрузку модулей, чтобы грузилось только то, что нужно на текущий момент, но это не просто и выглядит как решение выдуманной проблемы.
В целом, я категорически не согласен с мыслью:
Модуль HMPL схож по концепции с HTMX
иногда требуются дополнительные настройки, современные функци, идующие с fetch, и ещё плюшки работы с javascript и DOM деревом
Сам HTMX в чистом виде решает одну простую задачу: сходить на сервер по такому-то адресу, получить ответ и вставить его в указанное место. То есть эдакий декларативный сахар для fetch()
. Интерактивность при этом реализуется средствами сервера. То есть если вы нажали кнопку и под ней появился текст, это произошло, потому что сервер нарисовал кнопку вместе с текстом, отдал её в ответ на запрос и HTMX вставил это вместо исходное кнопки.
А если нужно что-то сделать с DOM на клиенте, то к HTMX берут дополнение в виде hyperscript (своего рода SQL для работы с DOM от того же автора) и пишут логику на нём. Или берут какой-то микрофреймворк, например alpine, petite-vue, или просто пишут на Vanilla JS.
Ладно, я понял, я просто не шарю за "нормализацию" XMLHTTPRequest в 2024 году. Сколько бы не было рассуждений на тему HTMX, но видно же код. Да, это удобно - я не спорю, да новый подход, тут тоже не спорю, да только вот не гибко, и то, что выдают за "IE13 совместимость", на практике же просто завлекалово. Это всё равно что выпускать программу на макбуки последние и хвастаться, что на мак ос пантере запуститься программа. Добавили бы хоть булеву функцию, чтобы поддерживать "новый" стандарт. Даже 2.0.3 версия, и то на XMLHTTPRequest. В fetch там кучу новых методов работы с сервером в новых EcmaScript введут, а мне что делать с этим как клиенту? Радоваться до усрачки, что я выбрал расхайпленный инструмент и теперь сижу придумываю, миксую там пакеты, чтобы хоть как-то заработало нормально? Ладно, пускай даже так, но всё таки если мы берём маломальски бизнесовый сайт, то как это вообще внедрять нормально? Про микрофронтенды я молчу, типо как это реализовать, когда direct DOM только? Как вот настраивать я сервер должен, если у него для одной части одни настройки расширенные, а на другой мне простоту наводить спецом для htmx?
Мне просто всё это не нравится. Я вижу, что идея классная и, на самом деле, прорывная, но как это реализовано, типо лол, в 2024 году стандарт с 2000 года используем. Ща ещё Object.assign и defineProperty вместо спред оператора и прокси будем использовать, вот красота. Либо, функцию конструктор вместо класса, тоже вот круто.
Я поэтому и пишу, что HTMX решает одну простую задачу — отправка HTTP-запросов, получение HTML и вставка в нужные места DOM. Тут нет разницы, делает он это при помощи XHR, fetch и какого синтаксиса JS. Взгляните на код, который выдают сборщики для prod: там тоже все спреды, классы, фетчи и прочее могут превращаться в старый добрый ES5, а то и ещё ниже бывает.
Тут важна сама идея. HTMX лишь один из вариантов реализации. Есть предшественник intercooler, есть идейный наследник alpine-ajax, есть похожие по концепции hotwire и livewire. Все они вполне используются и решают конкретные задачи. Миксовать пакеты, микрофронтенды, direct DOM — это вообще не про эту идею и HTMX в частности.
И да, HTMX не подходит для каких-то вещей, но также для каких-то подходит. Автор на сайте честно об этом написал, что круто, потому что почти ни у кого нет страницы, где было бы описано, где инструмент не подходит. Если HTMX не для вас, круто, просто не используйте его. Но вы написали статью, где сравниваете HTMX с Vue и HMPL, хотя эти инструменты лежат в разных плоскостях.
Типо, нахрена вообще HMPL нужен, я вот сидел, хотел сделать что-то типа языка шаблонов после cample. Я вижу, что с развитием server-side renderingа и вообще сервероориентированной разработкой - это реально будущее создания сайтов. Я вот смотрю модули, которые есть, и вижу, что у HTMX идея как раз классная, но реализация - это просто кринж какой-то. Типо, как я должен всерьёз это в проекте использовать? По началу, HMPL был чем-то похож на HTMX, но потом я просто это всё тестировал и это невероятно просто неудобным оказалось. Мне вообще это не нравилось, поэтому теперь сделано то, что я действительно хотел. Я не знаю, но по мне вот это:
import { compile ) from "hmpl-js";
const templateFn = compile(
`<div>
<form onsubmit="function prevent(e){e.preventDefault();};return prevent(event);" id="form">
<div class="form-example">
<label for="name">Enter your email: </label>
<input type="text" name="email" id="email" required />
</div>
<div class="form-example">
<input type="submit" value="Register!" />
</div>
</form>
<p>Email {
{
"src":"/api/register",
"after":"submit:#form",
}
} successfully registered!</p>
</div>`
);
const initFn = (ctx) => {
const event = ctx.request.event;
return {
body: new FormData(event.target, event.submitter),
credentials: "same-origin"
};
};
const obj = templateFn(initFn);
wrapper.appendChild(obj.response);
в идее сервероориентированности ну прям максимально удобно. Типо, хочешь отдельным файлом и не с javascript - пожалуйста - подключай лоадер для вебпака и кайфуй. Нужно настроить нормально RequestInit? Так вот, фигачишь функцию, получаешь конкретный элемент и делай что хочешь. Могу даже вспомнить работу с Яндекс картами, типо когда с api их работаешь, то там вообще кайф идёт от того, что всё контролируешь. Ну, типо я сделал просто язык шаблонов вот как хотел, реально мечта в разработке, что прям мне лично нравится при работе с модулями. Хочешь, подключай к любому фреймворку, библиотеке и др. там всё через javascript удобно настроить. Хочешь, делай 1000 узлов с серверным HTML в цикле. Вообще, супергибко, никакой нахер alpine.js или ещё 100 пакетов в дополнение просто не нужны. С микрофронтендами - да вообще без проблем. Каждый instance - это отдельная сущность, независимая, просто хоть во Vue компонент пихай, хоть в тесты - вообще по барабану.
*Булеву переменную, какую функцию
Сравнение некорректное, т.к. автор не понимает концепцию HTMX, а рассуждает привычными концепциями.
Для понимания концепции HTMX рекомендую бесплатную книжку - https://hypermedia.systems/book/contents/
Хорошо. Надо будет ещё с мемасиками ознакомиться
HMPL это разработка автора статьи, судя по github. Он конечно молодец - сделал в свои условные двадцать лет такой проект - похвально. Но как обычно - не разобрался в том что уже есть и сдел клон, в данном случае React шаблонов и т.п. технологий.
Очень трудной быть критичным к себе. По этому хочется убедить других в том что это решение имеет какой то смысл. Почти каждый программист проходит этот путь - сделать свой сильно урезанный клон существующей технологии, потом осознать что в этом нет ни какого смысла и единственная причина - просто хотелось как то себя проявить.))
"сдел клон, в данном случае React шаблонов и т.п. технологий" - да, клон одного, второго, третьего, пятого и десятого. Телеграм - это клон ватсапа, ватсап - это клон icq, discord - это клон скайпа. Знаю я такой подход. Технологии должны быть основаны, в большинстве случаев, уже на существующих концепциях и методах, придуманных заранее кем-то. Я постараюсь быть самокритичным к себе и проекту, поэтому сделаем нормально. Про "имеет хоть какой-то смысл" - это вообще отдельный разговор в том смысле, что тогда людям вообще не надо ничего делать и просто сидеть и кайфовать. Во всём есть смысл, даже в проектах, которые были изначально плохи. На основе их кода может вырасти что-то более стоящее. Так и в науке, медицине да и вообще в любых сферах.
"просто хотелось как то себя проявить.))" - я не знаю, типо к чему вообще эти скобочки, если в любой профессии люди хотят сделать что-то.
спасибо за статью,
мне остается не до конца понятным в чем преимущество по сравнению с next/nuxt. Они же по сути решают ту же самую проблему рендера на сервере. Есть существенная разница в размере получаемых файлов?
Я не использую HTMX потому, что не нахожу в нём ключевой для себя возможности работать с данными. Современный веб - это связка данных и разметки, и динамическое их обновление. Старый AngularJS, как мне кажется, уже всё для этого имеет, и размер тоже измеряется в килобайтах. HMPL сможет его заменить?
Старый ангуляр - это фреймворк. Размер берётся не самого модуля, а тех файлов, которые хранятся на сервере. HMPL - это язык шаблонов. Вы можете создать отдельный файл и писать там дополненную HTML разметку для простой работы с сервером, при это работая также с данными (можно генерировать RequestInit)
Lorem ipsum dolor sit amet, consectetur adipiscing elit