Попробую приноровиться к хабру и залью сюда перевод статьи с другого своего ресурса.
Это весьма самоуверенное, но, надеюсь, честное и точное сравнение Hyperstack и Hotwire.
Прежде всего, что это за вещи?
Оба решения помогают затащить современный UI в Rails.
Оба завязаны на Websockets для получения уведомлений об изменении состояния.
Hyperstack
-
Всё написано на Ruby (включая клиентский код)
-
Под капотом используется React для построения UI с возможностью доступа к библиотекам React
-
Легко поддерживает синхронизацию моделей Rails между UI и сервером. Зачастую без дополнительного кода
-
Убирает необходимость написания контроллеров (но при желании можно продолжать их использовать)
-
Отдает максимально возможное количество работы на сторону клиента
-
Предоставляет мощный механизм контроля доступа к данным, построенный на политиках Pundit"
-
Может использоваться в существующих Rails-приложениях
Hotwire
-
Это следующий виток эволюции Rails Turbolinks
-
Расширяет стандартную MVC систему Rails за счет передачи инкрементальных обновлений на уровень представления
-
Использует традиционные Rails подходы
-
Оставляет бльшую часть работы на стороне сервера, делая клиентскую часть очень лёгкой
-
Устраняет большую часть JS-кода (но не весь), которую вам может потребоваться писать
-
Поддерживается DHH и, предположительно, сообществом Rails
Чтобы бегло сравнить данные технологии, я обратился к простому приложению Tweet (https://gorails.com/episodes/hotwire-rails) и создал такое же на Hyperstack. На заметку: данный дизайн UI компонентов не моя идея, я позаимствовал код с минимально возможными изменениями.
Поскольку одна из основных целей Hyperstack состоит в уменьшении общего объема кода, начнём рассмотрение с числа строк. Сгененированные файлы и шаблоны, такие как layout и стили включать не будем, поскольку они совпадают.
Hyperstack - 78 lines vs Hotwire 156
Но строки - это еще не всё, какой инструмент будет легче в понимании и поддержке?
Рассмотрим, как каждый фреймворк реализует Tweet Card, отображающий твит и позволяет обновлять счетчики "лайков" и "ретвитов".
Hyperstack:
Hotwire:
Пока что оба приведенных участка кода очень похожи.
Hyperstack определяет React-компонент, берущий твит в качестве параметра, и формирует код на основании DSL. Этот DSL отражает нижележащую HTML-разметку с дополнительными компонентами в вашем приложении. Например EditTweet компонент, подключаемый в 11 строке.
Hotwire использует ERB для генерации HTML, используя ряд
вспомогательных функций, таких как turbo_frame_tag
и
т. д.
Как и React, Hyperstack является декларативным и state-driven инструментом. Когда пользователь нажимает на кнопку изменить, устанавливается состояние editing, что в свою очередь заставляет компонент перерисовать и подключить EditTweet компонент (строка 14). EditTweet в свою очередь эмитит события save или cancel, оба из которых возвращают editing state в состояние false. Всё это определяется и исполняется на стороне клиента.
Цель же Hotwire заключается в реализации логики на сервере таким образом, что нажатие на Edit просто отправляет запрос на сервер, который выполняет обновление компонента.
Когда пользователь нажимает Like или Retweet, Hyperstack
обрабатывает событие с помощью .on(:click)
, и
просто зовет ActiveRecord increment!
и обновляет
счетчик твита. Под капотом Hyperstack занимается поддержанием
локальной копии твита в синхронизированном с сервером состоянии и
пересылает все изменения всем участвующим клиентам (браузерам)
Hotwire тем временем выполняет обновления счётчиков так же, как и edit функция: передаёт работу серверу и требует наличия когда, обрабатывающего это. И действительно, тут есть три контроллера, которые выполняют работу по обработке изменений твита:
Таким образом, не смотря на то, что код Hyperstack изначально был немного длиннее, пользовательский интерфейс это еще не вся история. И чтобы html.erb действительно заработал, необходимо ещё 70+ строк и что ещё хуже UI-логика оказывается размазана по четырём файлам.
Но мы ещё не закончили. В добавок к .erb файлу и контроллерам
нам также необходимjson
файл, который выполняет
функции связующего API. К счастью, Hotwire поставляется с jbuilder,
так что это всего лишь 2 строки когда, но его надо написать
и поддерживать.
Погодите, мы ещё не закончили. Чтобы Hotwire знал, что ему
необходимо разослать изменения клиентам, вам надо добавить три
дополнительных колбэка (after_...
) в
twitter.rb
Мы закончили? Почти. Остался ещё один файл. Помните про
контроллеры? Теперь к ним надо добавить роуты, а это еще 3 строки в
другом файле. Честно говоря, Hyperstack тоже требует несколько
строк (две если быть точным) в routes.rb
, но они
никогда не будут меняться в течении жизни приложения.
Прежде чем я продолжу, давайте посмотрим с другой стороны. Допустим у вас уже есть рабочее приложение, к которому вы хотите добавить кнопку Like
Что для этого нужно?
Во-первых в обоих фреймворках вам надо добавить атрибут в модель данных, создав и выполнив миграцию. (Рельсы!)
Далее для Hotwire необходимо:
-
добавить ресурс в роуты
-
добавить контроллер (как мы видели это 14 строк)
-
не забыть обновить
json
, добавив в него новый атрибут -
и наконец добавить
button_to
тэг в_tweet.html.erb
Мы затронули четыре файла и добавили 16 строк кода, используя знания о шести подсистемах Rails - action controller, view helpers, jbuilder, active record и router - написали собственный код на Ruby, HTML и ERB.
Как выполняется та же задача на Hyperstack?
Как только закончили с миграциями надо добавить только:
BUTTON { "Likes (#{tweet.likes_count})" }.on(:click) { tweet.increment!(:likes_count) }
Для чего требуется только понимание функции active record
increment!
и HyperComponent DLS, что напрямую
относится к выполняемой работе.
В чем подвох?
Подвоха нет, просто другие цели. Hyperstack строился для максимизации эффективности программиста и для передачи работы с сервера на сторону клиента. Он достигает целей используя один замечательный язык, опираясь на Rails и используя девиз Rails о convention over configuration для устранения ненужных шаблонов.
Заявленная цель Hotwire состоит в том, чтобы сохранить контроль за приложением на сервере и он достигает её ценой ценой усложнения поддержки и понимаемости приложения. Он также использует более консервативный подход в архитектуре приложения, вместо того, чтобы отказываться от контроллеров и заменять ERB файлы на собственный DSL. Он основан на проверенных и надёжных техниках Rails, который привычны многим разработчикам.
Некоторые другие соображения
Это маленькое упражнение, но оно позволяет увидеть как две разные системы выполняют свои задачи. Я считаю, что с Hotwire становится сложнее, с Hyperstack проще. Я не могу этого доказать, но как я уже сказал это самоуверенная статья.
Ещё одно соображение касательно ценности участия в экосистеме React. Фундаментальная архитектура React, как декларативной и "state-driven" системы, делает результирующий код невероятно простым для написания и понимания. Я считаю, что гораздо проще (разумеется, после того, как преодолел порог вхождения) создавать высокофункциональный и поддерживаемый код в декларативном стиле. Более того, существует множество готовых компонентов React для решения самых разнообразных задач, что ещё больше сокращает объём кода, который необходимо писать и поддерживать.
И последнее: о ценности разработки на одном языке. Многие не считают это существенным, а работу программиста с несколькими языками и системами - само собой разумеющимся. Но это не так. Постоянное переключение контекста заставляет программиста растрачивать ценную энергию и думать о деталях реализации, вместо того, чтобы думать о системе в целом. Нет ничего, что могло бы сделать один язык лучше для разработки пользовательского интерфейса, а другой - для серверной части. Есть инструменты для компиляции практически любого языка на любую платформу, так почему бы не выбрать один язык, который можно использовать в масштабах всей системы? И если вы собираетесь выбрать язык, то Ruby трудно превзойти.
Оригинал: Hyperstack vs Hotwire от 26 февраля 2021 года. Автор: @catprint aka Mitch VanDuyn
От переводчика
Мы решили выбрать эту статью для того, чтобы осветить различные современные течения во фронтендной части Rails. Мы не определились до конца с подобными инструментами, однако на нескольких проектах начали использовать Stimulus и двигаемся в сторону Hotwire.