Авторский проект IT-специалиста Олега Барабанова Персональные публикации на тему IT и не только…

Впечатления от знакомства с микрофреймворком AlpineJS

В этом месяце я умудрился познакомиться в работе с двумя полезными для меня инструментами веб-разработки, неплохо отдохнуть в Удмуртии, съездив с супругой в прекрасный город Ижевск, а также посетив рок-фестиваль «Улетай». Удивительно, но даже на огромном рок-фестивале я с легкостью узнавал типичных программистов. Например Java-разработчиков я легко узнал по флагу с названием языка и типичным логотипом в виде чашки кофе, видел PHP-разработчиков в футболке PHP с логотипом в виде слона, а также встретил разработчиков из Tilda (узнал их по фирменной футболке).

Но я немного отвлекся от темы статьи. Как уже упоминал, я для себя открыл два новых инструмента, которые неплохо себя показали в работе — AlpineJS и HTMX, но в статье я решил уделить внимание пока только AlpineJS, поскольку про HTMX я хочу написать позднее, после того как чуть побольше с ним поработаю.

Проблема использования React/Vue/Angular в случае простейших рутинных задач с DOM

Реактивный подход очень удобен при решении рутинных задач при работе с DOM-моделью. Для реализации реактивности на ум сразу приходят React/Vue/Angular. Но проблема в том, что каждый из этих замечательных инструментов работает в своей экосистеме, со своим синтаксисом шаблонов, виртуальным DOM и зависит от кучи сторонних инструментов (например систем сборки). Такая ситуация отлично подходит для реализации сложных и самодостаточных веб-приложений. Но при этом эти инструменты иногда заметно избыточны, например при необходимости простой работы с DOM в уже сверстанном сайте, при этом избежав конфликтов со сторонними скриптами. Или сделать форму отправки заявки более интерактивной и с т.з. кода более наглядной, без кучи всяких addEventListener-ов и непонятной логики.

Ранее я при верстке сайта, в основном брал Vue c его замечательным компонентным подходом. И впринципе все было неплохо, кроме разве что того, что верстка очень сильно зависела от системы сборки (vite, webpack и пр.), что не очень удобно при создании шаблона сайта. Верстка состояла из кучи Vue компонентов, которые собирались в готовую верстку. Тут появляется сложность в том, что когда верстка уже натянута на CMS, вносить правки становится проблемно. Т.е. надо вначале внести правку в шаблонах Vue, затем пересобрать проект и постараться не сломав перетянуть его на CMS. Если это делается регулярно и обслуживается одной командой разработчиков, тогда можно настроить непрерывную интеграцию с автоматической пересборкой шаблона CMS, что по-логике является оптимальным решением. Но если с этим придется будет работать сторонним программистам, которым ради внесения небольшой правки в верстку сайта, придется будет научиться разбираться в компонентах Vue, в различных конфигах бандлеров и пр., то в таком случае, есть высокая вероятность, что эти разработчики не будут сильно разбираться и просто воткнут какой-нибудь костыль прямо в код шаблона (см. теорию разбитых окон).

Почему я обратил внимание на AlpineJS

В общем для подобных ситуаций я стал искать более подходящее решение, которое не требовало бы знания кучи сторонних утилит и имело минимум зависимостей. В процессе поисков наткнулся на быстро набирающий популярность проект AlpineJS, который представляет собой небольшой JS микрофреймворк, позволяющий реализовать любую интерактивность в реактивном стиле, как и в React/Vue/Angular.

Лично меня AlpineJS заинтересовал благодаря некоторым его особенностям:

Кстати, хочу заметить, что разработчики AlpineJS явно вдохновлялись Vue, ибо даже в простейших примерах заметна схожесть. Вот взгляните на простой пример счетчика на Alpine и на Vue:

<!-- Пример на AlpineJS -->

<div x-data="{ count: 0 }">
    <button x-on:click="count++">Increment</button>
    <span x-text="count"></span>
</div>
<!-- Пример на Vue -->

<script setup>
import { ref } from 'vue'

const count = ref(0);
</script>

<template>
    <button v-on:click="count++">Increment</button>
    <span v-text="count"></span>
</template>

Как видите, похожего немало, но напомню, что хоть Vue и AlpineJS имеют схожие черты, у них разные весовые категории и они заточены под разные задачи. Хотя не могу не отметить, что разработчики Vue пытались сделать свой минималистичный вариант Vue в виде Petite-Vue (как альтернативу AlpineJS), но судя по коммитам, проект видимо давно заброшен. А вот AlpineJS активно развивается.

Расширения AlpineJS

Хоть AlpineJS и является микрофреймворком, но функционал расширения в нем все-таки заложен и более того, некоторые плагины развиваются самой командой разработчиков AlpineJS.

Из множества официальных плагинов, на деле я успел поработать пока что с двумя: Intersect и Persist.

Intersect работает поверх IntersectionObserver и предоставляет возможность удобно, декларативно и в реактивном стиле реагировать на пересечения элемента с его родителем или областью видимости документа. Это очень удобно, когда допустим нужно запустить какую-либо анимацию, во время скролла.

Хороший пример для наглядности как-раз представлен у них в документации:

<div x-data="{ shown: false }" x-intersect="shown = true">
    <div x-show="shown" x-transition>
        I'm in the viewport!
    </div>
</div>

Плагин Persist представляет собой менеджер состояний, благодаря которому можно хранить состояние в LocalStorage или SessionStorage, а также взаимодействовать с хранимыми значениями реактивно. По назначению в чем-то схоже с Vuex или Pinia из мира Vue.

С остальными официальными плагинами я пока еще не работал, но думаю так или иначе еще успею с ними познакомиться. Да и в общем, тема плагинов к AlpineJS достойна более подробного рассмотрения в виде отдельной статьи.

AlpineJS и Tailwind

Вот совсем не могу не отметить тот момент, что AlpineJS очень гармонирует при работе с Tailwind. Эти два фреймворка прям отлично дополняют друг друга, при этом как-бы странно не звучало, оставаясь в рамках нативной HTML разметки.

Конечно, что-то подобное с первого раза может испугать:

<div class="flex flex-col justify-center gap-2 bg-emerald-50 px-4 py-6" x-data="{ shown: false }" x-intersect="shown = true">
    <div class="text-white text-2xl md:text-3xl lg:text-4xl" x-show="shown" x-transition>
        I'm in the viewport!
    </div>
</div>

С другой стороны, тут вам и реактивность, тут и адативность, тут весь и UI и при этом все это фактически представлено в виде HTML разметки. Соответственно с этим беспроблем будет работать любая IDE, умеющая работать с HTML. Ну и тупо различные парсеры HTML тоже вполне легко могут работать с этим, да и с поисковыми системами будет попроще.

Заключение

Для меня AlpineJS быстро стал одним из тех инструментов, который я стал активно использовать в разработке. Его на деле оказалось удобно использовать в череде тех задач, где Vue избыточен. В тоже время для разработки самодостаточных веб-приложений он малоприменим, поскольку в нем нет поддержки разделения кода на отдельные самодостаточные веб-компоненты, да и возможности в нем ограничены.

На мой взгляд AlpineJS ни в коем случае не конкурирует с Vue/React/Angular, а просто занимает свою нишу применения, фактически являясь маленьким карманным JS-микрофреймворком, который не требует никаких зависимостей. И соответственно в своей профессиональной деятельности вы можете использовать любой из этих инструментов, подбирая подходящий в зависимости от задач. А как-никак, подбор оптимального стека технологий для проекта - это тоже важный профессиональный навык, который нужно развивать.