Не знаю где, но я уже видел этот подход, вот правда не помню где)
Если поискать на NPM, то там есть пакеты с похожими идеями, я тоже видел.
Но с другой стороны, это как-то как будто бы избыточно - уж очень многословно. Особенно вызов функции на каждый атрибут.
Про многословность согласен, особенно если атрибутов много (какие-нибудь инпуты, например). С другой стороны унификация, всё — функции. Были идеи всё-таки допустить передачу объектов внутрь attr/prop. Или реализовать функции attrs/props, принимающие объекты.
Или предусмотреть передачу в функцию создания элемента аргумента в виде объекта. Но тогла вопрос: обрабатывать его как свойства или как атрибуты? Вроде как большинство атрибутов отражаются в свойства, но не все и есть свойства без соответствующих атрибутов. А если обрабатывать как свойства, то возникают проблемы с поддержкой веб-компонентов и иногда нужны именно атрибуты. Поэтому остановился на таком подходе.
В теории можно добавить это в статью как еще один способ, для полноты картины, если вы не против.
Можете добавить, я не против.
Также, если данная реализация есть где-то на гитбах, я бы взглянул. Сбросьте в личку если есть такая возможность.
К сожалению, никуда не заливал. Валяется где-то среди экспериментов/пет-проектов)
Читал статью и словил дежавю, потому что тоже пробовал выразить шаблоны нативным синтаксисом JS и без теговых шаблонных литералов. Вдохновлялся такими вещами, как Flutter, Jetpack Compose, SwiftUI и прочими технологиями, где шаблоны выражены средствами самого языка.
Ход мыслей был примерно как в статье. Хотелось получить лаконичный синтаксис без лишних скобок, массивов и JSON. В итоге пришёл к тому, что всё есть функция. Получилось что-то такое:
attr и prop устанавливают атрибуты и свойства узлам.aria и data — хелперы для ARIA-атрибутов и data-атрибутов, можно задавать и через attr/prop. Остальные аргументы функции — children. Если передан массив, он джойнится. Примитивные значения и объектные обёртки преобразуются к строкам и вставляются как текстовые ноды.
Пробовал разные варианты if и for, в итоге тоже получились функции, но вот с этим уже сложнее было. Потом натягивал на всё это реактивность через Proxy. В общем эксперимент получился интересный и чем-то похож на то, что описано в статье.
К сожалению, id уникальны в рамках документа и на данный момент бороться с этим можно только генерируя случайные id. Можете посмотреть в сторону Shadow DOM, он как раз создаёт скоуп, в рамках которого id не будут конфликтовать с другими на странице, даже если будут повторяться. Но Shadow DOM несёт за собой дополнительную специфику, нужно иметь это ввиду.
Судя по примеру кода и описанию задумки, вам как раз бы подошёл Shadow DOM и веб-компоненты в целом. Как раз позволят запаковать шаблон, изолировать id и бонусом автоматическое инстанцирование.
Уже нет необходимости в этом input[type=radio]:checked + label ~ label со всякими + и ~. У радиокнопки достаточно указать appearance: none и она превращается в бокс, который можно стилизовать практически как угодно.
Я поэтому и пишу, что HTMX решает одну простую задачу — отправка HTTP-запросов, получение HTML и вставка в нужные места DOM. Тут нет разницы, делает он это при помощи XHR, fetch и какого синтаксиса JS. Взгляните на код, который выдают сборщики для prod: там тоже все спреды, классы, фетчи и прочее могут превращаться в старый добрый ES5, а то и ещё ниже бывает.
Тут важна сама идея. HTMX лишь один из вариантов реализации. Есть предшественник intercooler, есть идейный наследник alpine-ajax, есть похожие по концепции hotwire и livewire. Все они вполне используются и решают конкретные задачи. Миксовать пакеты, микрофронтенды, direct DOM — это вообще не про эту идею и HTMX в частности.
И да, HTMX не подходит для каких-то вещей, но также для каких-то подходит. Автор на сайте честно об этом написал, что круто, потому что почти ни у кого нет страницы, где было бы описано, где инструмент не подходит. Если HTMX не для вас, круто, просто не используйте его. Но вы написали статью, где сравниваете HTMX с Vue и HMPL, хотя эти инструменты лежат в разных плоскостях.
иногда требуются дополнительные настройки, современные функци, идующие с fetch, и ещё плюшки работы с javascript и DOM деревом
Сам HTMX в чистом виде решает одну простую задачу: сходить на сервер по такому-то адресу, получить ответ и вставить его в указанное место. То есть эдакий декларативный сахар для fetch(). Интерактивность при этом реализуется средствами сервера. То есть если вы нажали кнопку и под ней появился текст, это произошло, потому что сервер нарисовал кнопку вместе с текстом, отдал её в ответ на запрос и HTMX вставил это вместо исходное кнопки.
А если нужно что-то сделать с DOM на клиенте, то к HTMX берут дополнение в виде hyperscript (своего рода SQL для работы с DOM от того же автора) и пишут логику на нём. Или берут какой-то микрофреймворк, например alpine, petite-vue, или просто пишут на Vanilla JS.
HTMX — это попытка (и достаточно успешная на мой взгляд) привнести новый подход к разработке веб-приложений, ориентированый на серверный рендеринг, с добавлением некоторых недостающих вещей в HTML.
Идея в том, чтобы дать браузерам выдохнуть и не перемалывать мегабайты JavaScript на устройствах пользователей, чтобы отрисовать интерфейс. Вместе с этим уйти от издержек, которые приносят современные JavaScript-комбайны.
Вместо этого пусть браузеры делают то, что было заложено в них при создании — слать HTTP-запросы к серверу, получать в ответ HTML и рендерить его. А браузеры делают это чертовски хорошо и быстро. И пусть логика отрисовки и работы с данными будет на сервере, где ей и место. А тонкая библиотека JavaScript будет инициировать нужные HTTP-запросы и вставлять результат в нужные места документа.
Подход не новый, так делали деды ещё до появления всяких React-ов. HTMX просто предложил простой и декларативный синтаксис плюс старый советский рендеринг на сервере. И простота этого подкупила, особенно на фоне оверинжиниринга в современном фронтенде. А дополнительная популярность возникла из-за забавных мемов и специфической "рекламной кампании", если это можно так назвать.
Вот это то, что мне не нравится во многих фреймворках. Код нужно писать в специально придуманном файле. Для подсветки синтаксиса нужен специальный плагин с Language Server и IDE, которая поддерживает плагин. Разметку нужно писать на специальном диалекте при наличии HTML. Для стилей нужны какие-то пакеты, иначе нельзя писать CSS. Вместо JavaScript нужно писать на каком-то мета-языке. Для перехода между страницами нужен ещё один пакет, потому что нельзя использовать a[href]. И чтоб всё это заработало, ещё нужен сборщик, десять плагинов для него, пять конфигов, npm и node нужных версий и 5 минут билда. Утрирую, но суть примерно такая.
WP использует рендер на сервере, что на текущий момент является моветоном
А по-моему наоборот все потихоньку возвращаются на сервер. Уже пару лет есть мода на SSR и всякие там Next/Nuxt/etc, потому что SEO, производительность, кэш, Server Components и т.д. Тот же нашумевший HTMX предлагает рендерить фрагменты HTML на сервере классическим бекендом с шаблонизаторами.
Ну а что да WP, он живёт себе, спокойно развивается, всё ещё занимает огромную нишу и используется на трети сайтов в интернете. Кривой, косой по историческим причинам, но простой, работает и решает огромное количество задач, при этом не стоит как крыло самолёта.
Можно использовать <picture> + батарею <source> с разными форматами + <img> фоллбэк. Браузеры, которые умеют, загрузят WebP, которые не умеют, откатятся к JPEG/PNG.
Либл можно на сервере читать заголовок Accept, там будет список поддерживаемых форматов. И отдавать разные форматы в зависимости от заголовка.
А для старых устройств можно под картинкой ссылку на скачивание старого доброго JPEG сделать.
На мой взгляд причина та же, почему когда-то в PHP, Java и других языках ушли от шаблонов с вставками кода к шаблонизаторам. Язык даёт слишком большую гибкость и это не всегда нужно.
Об этом говорил создатель Vue в одном из своих докладов.
Байндинга с шаблоном, директив в шаблоне, реактивных переменных, не строковых пропсов. Добавляем это и получаем Vue
Или Lit. Он, всё же, by design разработан для создания веб-компонентов и приложений на их базе. Vue всё же был создан несколько для другого, что не отменяет возможности скомпилировать Vue-компонент в веб-компонент.
Здесь важно нарисовать кнопку на экране и раскасть её, максимум отправить AJAX-запрос на сервер.
А вы уверены? Тут в соседней статье человек, практикующий найм, делится довольно внушительным списком навыков, которыми должен обладать хороший фронтенд-разработчик. В то же время соискатели жалуются на возросшую сложность всего этого и завышенные требования от работадателей. Где же правда?
Например, можно изобрести своё собственное пространство имён для работы с параметрами CSS, что повышает читаемость
Вообще по стандарту HTML нельзя. У элемента могут быть указаны глобальные атрибуты, специфические для этого элемента атрибуты и любые data-* атрибуты. Любые другие атрибуты с точки зрения стандарта считаются невалидными. Из-за лояльности HTML как-бы и ладно, ничего не будет, а селекторы по атрибуту и JS сработают. Но всё-таки так нельзя делать.
любой тег, не распознанный парсером — это неизвестный элемент, который можно свободно стилизовать как угодно
Не совсем так. Элемент считается неизвестным HTMLUnknownElement, если он не является одним из стандартных или не содержит в названии как минимум одного дефиса. Если дефис есть, то парсер рассматривает элемент как потенциальный пользовательский элемент, который пока ещё не зарегистрирован. В таком случае он будет HTMLElement.
С точки зрения HTML всё может быть сделано правильно. Но это лишь один из факторов. Текст может быть уникальным, и описания по 1200 символов, но само содержание текстов, ключевые слова, формулировки могут не нравиться гуглу.
Также сайт может иметь все метатеги и правильную иерархию заголовков, но быть медленным как для пользователя, так и с точки зрения метрик Lighthouse.
Если сайт работает как SPA на модных фреймворках, это тоже может свести на нет усилия по созданию структуры и уникальных текстов. В общем нужно детальнее копать.
Вы ссылаетесь на устаревшую и уже не актуальную версию спецификации, ещё и на снапшот от 2013 года. Официальная спецификация — HTML Living Standard.
В старых стандартах действительно можно было использовать сколько угодно <h1>, это относилось к попытке реализации алгоритма outline с вычислением уровня заголовка на основе вложенности секционных элементов.
Но этот алгоритм не был реализован ни одним из браузеров, и в конечном счёте его удалили из стандарта. Сейчас в примерах используются уровни заголовков, хотя и есть один пример с несколькими <h1>.
Но если выйти за пределы стандартов HTML и посмотреть на те же обшепринятые практики SEO или стандарты доступности, то всё-же правило "один <h1> на страницу" актуально. Более того, это даже логично.
Если поискать на NPM, то там есть пакеты с похожими идеями, я тоже видел.
Про многословность согласен, особенно если атрибутов много (какие-нибудь инпуты, например). С другой стороны унификация, всё — функции. Были идеи всё-таки допустить передачу объектов внутрь
attr/prop. Или реализовать функцииattrs/props, принимающие объекты.Или предусмотреть передачу в функцию создания элемента аргумента в виде объекта. Но тогла вопрос: обрабатывать его как свойства или как атрибуты? Вроде как большинство атрибутов отражаются в свойства, но не все и есть свойства без соответствующих атрибутов. А если обрабатывать как свойства, то возникают проблемы с поддержкой веб-компонентов и иногда нужны именно атрибуты. Поэтому остановился на таком подходе.
Можете добавить, я не против.
К сожалению, никуда не заливал. Валяется где-то среди экспериментов/пет-проектов)
Можно, но не нужно :) Все эти "хаки" вредят доступности и портят UX. Не стоит зло употреблять с пуризмом CSS.
Читал статью и словил дежавю, потому что тоже пробовал выразить шаблоны нативным синтаксисом JS и без теговых шаблонных литералов. Вдохновлялся такими вещами, как Flutter, Jetpack Compose, SwiftUI и прочими технологиями, где шаблоны выражены средствами самого языка.
Ход мыслей был примерно как в статье. Хотелось получить лаконичный синтаксис без лишних скобок, массивов и JSON. В итоге пришёл к тому, что всё есть функция. Получилось что-то такое:
Что превращается в это:
attrиpropустанавливают атрибуты и свойства узлам.ariaиdata— хелперы для ARIA-атрибутов и data-атрибутов, можно задавать и черезattr/prop. Остальные аргументы функции — children. Если передан массив, он джойнится. Примитивные значения и объектные обёртки преобразуются к строкам и вставляются как текстовые ноды.Пробовал разные варианты
ifиfor, в итоге тоже получились функции, но вот с этим уже сложнее было. Потом натягивал на всё это реактивность через Proxy. В общем эксперимент получился интересный и чем-то похож на то, что описано в статье.К сожалению,
idуникальны в рамках документа и на данный момент бороться с этим можно только генерируя случайныеid. Можете посмотреть в сторону Shadow DOM, он как раз создаёт скоуп, в рамках которогоidне будут конфликтовать с другими на странице, даже если будут повторяться. Но Shadow DOM несёт за собой дополнительную специфику, нужно иметь это ввиду.Судя по примеру кода и описанию задумки, вам как раз бы подошёл Shadow DOM и веб-компоненты в целом. Как раз позволят запаковать шаблон, изолировать
idи бонусом автоматическое инстанцирование.Уже нет необходимости в этом
input[type=radio]:checked + label ~ labelсо всякими+и~. У радиокнопки достаточно указатьappearance: noneи она превращается в бокс, который можно стилизовать практически как угодно.Я поэтому и пишу, что HTMX решает одну простую задачу — отправка HTTP-запросов, получение HTML и вставка в нужные места DOM. Тут нет разницы, делает он это при помощи XHR, fetch и какого синтаксиса JS. Взгляните на код, который выдают сборщики для prod: там тоже все спреды, классы, фетчи и прочее могут превращаться в старый добрый ES5, а то и ещё ниже бывает.
Тут важна сама идея. HTMX лишь один из вариантов реализации. Есть предшественник intercooler, есть идейный наследник alpine-ajax, есть похожие по концепции hotwire и livewire. Все они вполне используются и решают конкретные задачи. Миксовать пакеты, микрофронтенды, direct DOM — это вообще не про эту идею и HTMX в частности.
И да, HTMX не подходит для каких-то вещей, но также для каких-то подходит. Автор на сайте честно об этом написал, что круто, потому что почти ни у кого нет страницы, где было бы описано, где инструмент не подходит. Если HTMX не для вас, круто, просто не используйте его. Но вы написали статью, где сравниваете HTMX с Vue и HMPL, хотя эти инструменты лежат в разных плоскостях.
Сам HTMX в чистом виде решает одну простую задачу: сходить на сервер по такому-то адресу, получить ответ и вставить его в указанное место. То есть эдакий декларативный сахар для
fetch(). Интерактивность при этом реализуется средствами сервера. То есть если вы нажали кнопку и под ней появился текст, это произошло, потому что сервер нарисовал кнопку вместе с текстом, отдал её в ответ на запрос и HTMX вставил это вместо исходное кнопки.А если нужно что-то сделать с DOM на клиенте, то к HTMX берут дополнение в виде hyperscript (своего рода SQL для работы с DOM от того же автора) и пишут логику на нём. Или берут какой-то микрофреймворк, например alpine, petite-vue, или просто пишут на Vanilla JS.
HTMX — это попытка (и достаточно успешная на мой взгляд) привнести новый подход к разработке веб-приложений, ориентированый на серверный рендеринг, с добавлением некоторых недостающих вещей в HTML.
Идея в том, чтобы дать браузерам выдохнуть и не перемалывать мегабайты JavaScript на устройствах пользователей, чтобы отрисовать интерфейс. Вместе с этим уйти от издержек, которые приносят современные JavaScript-комбайны.
Вместо этого пусть браузеры делают то, что было заложено в них при создании — слать HTTP-запросы к серверу, получать в ответ HTML и рендерить его. А браузеры делают это чертовски хорошо и быстро. И пусть логика отрисовки и работы с данными будет на сервере, где ей и место. А тонкая библиотека JavaScript будет инициировать нужные HTTP-запросы и вставлять результат в нужные места документа.
Подход не новый, так делали деды ещё до появления всяких React-ов. HTMX просто предложил простой и декларативный синтаксис плюс старый советский рендеринг на сервере. И простота этого подкупила, особенно на фоне оверинжиниринга в современном фронтенде. А дополнительная популярность возникла из-за забавных мемов и специфической "рекламной кампании", если это можно так назвать.
Проблема с
prefers-reduced-motionв том, что многие как раз об этом не заботятся.Вот это то, что мне не нравится во многих фреймворках. Код нужно писать в специально придуманном файле. Для подсветки синтаксиса нужен специальный плагин с Language Server и IDE, которая поддерживает плагин. Разметку нужно писать на специальном диалекте при наличии HTML. Для стилей нужны какие-то пакеты, иначе нельзя писать CSS. Вместо JavaScript нужно писать на каком-то мета-языке. Для перехода между страницами нужен ещё один пакет, потому что нельзя использовать a[href]. И чтоб всё это заработало, ещё нужен сборщик, десять плагинов для него, пять конфигов, npm и node нужных версий и 5 минут билда. Утрирую, но суть примерно такая.
А по-моему наоборот все потихоньку возвращаются на сервер. Уже пару лет есть мода на SSR и всякие там Next/Nuxt/etc, потому что SEO, производительность, кэш, Server Components и т.д. Тот же нашумевший HTMX предлагает рендерить фрагменты HTML на сервере классическим бекендом с шаблонизаторами.
Ну а что да WP, он живёт себе, спокойно развивается, всё ещё занимает огромную нишу и используется на трети сайтов в интернете. Кривой, косой по историческим причинам, но простой, работает и решает огромное количество задач, при этом не стоит как крыло самолёта.
Можно использовать
<picture>+ батарею<source>с разными форматами +<img>фоллбэк. Браузеры, которые умеют, загрузят WebP, которые не умеют, откатятся к JPEG/PNG.Либл можно на сервере читать заголовок Accept, там будет список поддерживаемых форматов. И отдавать разные форматы в зависимости от заголовка.
А для старых устройств можно под картинкой ссылку на скачивание старого доброго JPEG сделать.
На мой взгляд причина та же, почему когда-то в PHP, Java и других языках ушли от шаблонов с вставками кода к шаблонизаторам. Язык даёт слишком большую гибкость и это не всегда нужно.
Об этом говорил создатель Vue в одном из своих докладов.
Или Lit. Он, всё же, by design разработан для создания веб-компонентов и приложений на их базе. Vue всё же был создан несколько для другого, что не отменяет возможности скомпилировать Vue-компонент в веб-компонент.
Хотел уточнить у вас один момент, но случайно оставил отдельным комментом, он ниже.
А вы уверены? Тут в соседней статье человек, практикующий найм, делится довольно внушительным списком навыков, которыми должен обладать хороший фронтенд-разработчик. В то же время соискатели жалуются на возросшую сложность всего этого и завышенные требования от работадателей. Где же правда?
Вообще по стандарту HTML нельзя. У элемента могут быть указаны глобальные атрибуты, специфические для этого элемента атрибуты и любые
data-*атрибуты. Любые другие атрибуты с точки зрения стандарта считаются невалидными. Из-за лояльности HTML как-бы и ладно, ничего не будет, а селекторы по атрибуту и JS сработают. Но всё-таки так нельзя делать.Не совсем так. Элемент считается неизвестным
HTMLUnknownElement, если он не является одним из стандартных или не содержит в названии как минимум одного дефиса. Если дефис есть, то парсер рассматривает элемент как потенциальный пользовательский элемент, который пока ещё не зарегистрирован. В таком случае он будетHTMLElement.Не сломается, если использовать CUSTOM_ELEMENTS_SCHEMA
С точки зрения HTML всё может быть сделано правильно. Но это лишь один из факторов. Текст может быть уникальным, и описания по 1200 символов, но само содержание текстов, ключевые слова, формулировки могут не нравиться гуглу.
Также сайт может иметь все метатеги и правильную иерархию заголовков, но быть медленным как для пользователя, так и с точки зрения метрик Lighthouse.
Если сайт работает как SPA на модных фреймворках, это тоже может свести на нет усилия по созданию структуры и уникальных текстов. В общем нужно детальнее копать.
Вы ссылаетесь на устаревшую и уже не актуальную версию спецификации, ещё и на снапшот от 2013 года. Официальная спецификация — HTML Living Standard.
В старых стандартах действительно можно было использовать сколько угодно
<h1>, это относилось к попытке реализации алгоритма outline с вычислением уровня заголовка на основе вложенности секционных элементов.Но этот алгоритм не был реализован ни одним из браузеров, и в конечном счёте его удалили из стандарта. Сейчас в примерах используются уровни заголовков, хотя и есть один пример с несколькими
<h1>.Но если выйти за пределы стандартов HTML и посмотреть на те же обшепринятые практики SEO или стандарты доступности, то всё-же правило "один
<h1>на страницу" актуально. Более того, это даже логично.