Обновить
2

Пользователь

2
Подписчики
Отправить сообщение

Не знаю где, но я уже видел этот подход, вот правда не помню где)

Если поискать на NPM, то там есть пакеты с похожими идеями, я тоже видел.

Но с другой стороны, это как-то как будто бы избыточно - уж очень многословно. Особенно вызов функции на каждый атрибут.

Про многословность согласен, особенно если атрибутов много (какие-нибудь инпуты, например). С другой стороны унификация, всё — функции. Были идеи всё-таки допустить передачу объектов внутрь attr/prop. Или реализовать функции attrs/props, принимающие объекты.

Или предусмотреть передачу в функцию создания элемента аргумента в виде объекта. Но тогла вопрос: обрабатывать его как свойства или как атрибуты? Вроде как большинство атрибутов отражаются в свойства, но не все и есть свойства без соответствующих атрибутов. А если обрабатывать как свойства, то возникают проблемы с поддержкой веб-компонентов и иногда нужны именно атрибуты. Поэтому остановился на таком подходе.

В теории можно добавить это в статью как еще один способ, для полноты картины, если вы не против.

Можете добавить, я не против.

Также, если данная реализация есть где-то на гитбах, я бы взглянул. Сбросьте в личку если есть такая возможность.

К сожалению, никуда не заливал. Валяется где-то среди экспериментов/пет-проектов)

Можно, но не нужно :) Все эти "хаки" вредят доступности и портят UX. Не стоит зло употреблять с пуризмом CSS.

Читал статью и словил дежавю, потому что тоже пробовал выразить шаблоны нативным синтаксисом JS и без теговых шаблонных литералов. Вдохновлялся такими вещами, как Flutter, Jetpack Compose, SwiftUI и прочими технологиями, где шаблоны выражены средствами самого языка.

Ход мыслей был примерно как в статье. Хотелось получить лаконичный синтаксис без лишних скобок, массивов и JSON. В итоге пришёл к тому, что всё есть функция. Получилось что-то такое:

article(
  attr('class', 'card'),
  data('type', 'featured'),
  aria('labelledby', 'heading_id'),
  prop('id', 7425639),
  comment('Article template'),
  img(
    attr('src', '...'),
    attr('alt', '...'),
    prop('className', 'img')
  ),
  h2(
    prop('id', 'heading_id'),
    a(
      attr('href', '/article/7425639'),
      'Read more'
    )
  ),
  p(`Article description`),
  p(
    text('Posted on: '),
    time('2024-12-17')
  )
)

Что превращается в это:

<article class="card" data-type="featured" aria-labelleby="heading_id" id="7425639">
  <!-- Article template -->
  <img src="..." alt="..." class="img">
  <h2 id="heading_id">
    <a href="/article/7425639">Read more</a>
  </h2>
  <p>Article description</p>
  <p>Posted on: <time>2024-12-17</time></p>
</article>

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 просто предложил простой и декларативный синтаксис плюс старый советский рендеринг на сервере. И простота этого подкупила, особенно на фоне оверинжиниринга в современном фронтенде. А дополнительная популярность возникла из-за забавных мемов и специфической "рекламной кампании", если это можно так назвать.

Проблема с prefers-reduced-motion в том, что многие как раз об этом не заботятся.

Вот это то, что мне не нравится во многих фреймворках. Код нужно писать в специально придуманном файле. Для подсветки синтаксиса нужен специальный плагин с 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.

Не сломается, если использовать CUSTOM_ELEMENTS_SCHEMA

С точки зрения HTML всё может быть сделано правильно. Но это лишь один из факторов. Текст может быть уникальным, и описания по 1200 символов, но само содержание текстов, ключевые слова, формулировки могут не нравиться гуглу.

Также сайт может иметь все метатеги и правильную иерархию заголовков, но быть медленным как для пользователя, так и с точки зрения метрик Lighthouse.

Если сайт работает как SPA на модных фреймворках, это тоже может свести на нет усилия по созданию структуры и уникальных текстов. В общем нужно детальнее копать.

Вы ссылаетесь на устаревшую и уже не актуальную версию спецификации, ещё и на снапшот от 2013 года. Официальная спецификация — HTML Living Standard.

В старых стандартах действительно можно было использовать сколько угодно <h1>, это относилось к попытке реализации алгоритма outline с вычислением уровня заголовка на основе вложенности секционных элементов.

Но этот алгоритм не был реализован ни одним из браузеров, и в конечном счёте его удалили из стандарта. Сейчас в примерах используются уровни заголовков, хотя и есть один пример с несколькими <h1>.

Но если выйти за пределы стандартов HTML и посмотреть на те же обшепринятые практики SEO или стандарты доступности, то всё-же правило "один <h1> на страницу" актуально. Более того, это даже логично.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность