Влад Кибенко // qbnk // Mini Apps, Development and Me
1.65K subscribers
639 photos
116 videos
5 files
544 links
Стример, разработчик, блогер. Улучшаю платформу Telegram Mini Apps, создаю исключительные продукты, выступаю на конференциях.

Лобби: t.me/heyqbnk_chat
Twitch: twitch.tv/qbnk
Download Telegram
👩‍💻 Non-null assertion operator в Typescript и вредные советы

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

Non-null assertion operator — это оператор, который принуждает TypeScript исключить из типов переменной такие типы как null и undefined. Вот пример:
function createPayload(): Record<string, unknown> {
let payload: Record<string, unknown> | undefined;
// ...
return payload!; // <-
}


Кажется безопасным применять этот оператор тогда, когда "мамой клянусь там будет значение". Вопрос встаёт только тогда, когда мамой кляться кажется безопасным. Ну и когда не кажется в принципе.

Реалии разработки таковы, что разработать проект стоит дешевле, чем поддерживать его в долгосрок. По этой причине, собственно, нейронные сети могут быть проблемой — они могут быстро накидать вам какой-то проект, но вот поддерживать его дальше уже будет считаться вашей обязанностью. Как можно догадаться, поддерживать проект, в котором вы ничего не понимаете, потому что по факту не вы являетесь его владельцем — идея амбициозная. Но сейчас не об этом.

Давайте рассмотрим другой пример:
let count: number | undefined;

function setCount(value: number) {
count = value;
}

function getCount(): number {
return number!;
}


Это упрощенный вариант того, что может быть в production-коде, просто для демонстрации. Функцию getCount написали такой, с non-null assertion, потому что там, где она вызывается, есть уверенность, что setCount уже где-то в проекте вызвали.

Теперь возвращаясь к теме о том, что поддержка проекта — это одна из самых тяжелых статей расходов. Проект — это практически всегда большая кодовая база, которая поддерживается множеством (не одним) разработчиков. Сокровенное знание о том, что "по-любому" где-то что-то вызвали, присутствует не у всех, а что более важно — это не вечно.

Какой-то разработчик по ошибке может снести эту, казалось бы, аксиому, в виде вызова нужной функции, а другой будет в пятницу вечером сидеть и искать, почему в каком-то уголке приложения произошёл отрыв жопы. Что самое страшное — далеко не всегда можно идентифицировать точную проблему, а в данном случае — что getCount вернул что-то не то. Ошибка может вообще говорить не об этом, а о том, что попытались обратиться к какому-то полю какого-то объекта, и не вышло. Смотрим в минифицированный код и видим фигу. Смотрим в stack trace исходников, начинаем идти вверх по вызовам, перекидывая взгляд на исходники со словами "да че за х, такой ошибки не может быть". Бурчим себе под нос "да нормально же всё было, код собирается". Спустя час исследований, понимаем, что мы просто заткнули TypeScript, и не дали помочь нам сказать об ошибке.

Что самое грустное, можно было потратить не 1 час, а всего лишь 5 минут! Докрутим прошлый пример:
function getCount(): number {
if (count === undefined) {
throw new Error('Oops, for some reason count is missing value :(');
}
return count;
}


Это не спасёт от ошибки в рантайме, но и не должно, для этого есть тесты. Вот только вместо пресловутого часа можно было потратить категорически меньше времени для устранения проблемы.

Как можно было догадаться, этот пост родился не из вредности, а из личного опыта. Однажды мне пришлось поучаствовать в ситуации, именуемой "по-любому всё будет ок", и потратить 2 часа своей жизни, чтобы осознать тщетность бытия. Как кто-то когда-то сказал, "если что-то может сломаться, оно обязательно сломается", поэтому не ленитесь вставлять такие мелочи для экономии самого важного ресурса, который у вас есть.

На самом деле, проблема не связана именно с этим оператором, а с подходом "всё будет збс". В этот подход, например, вписывается использование оператора as. Понятно, что всегда надо исходить из конкретной ситуации и не сходить по этой теме с ума, но про потенциальные последствия не стоит забывать.

Если лень постоянно писать if, воспользуйтесь assert-ами:
function getCount(): number {
assert(count !== undefined, 'Oops, for some reason count is missing value :(');
return count;
}


#ts #typescript
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥75💯2
Трансляция запущена!

Реализую функционал со splash screen-ом в Платформере #3 / Vue / GoLang / !project

— Software and Game Development
twitch.tv/qbnk
1
Мессенджер MAX посчитал хорошей идеей подписать меня на паблик без моего ведома
😁22🥰6👍3🔥2
Просто немного фоток/скринов из последних 4 дней отпуска в Питере. Так много я ещё в жизни не ходил.
🔥23😍65
👨‍💻 ОТПУСК — В С Ё

Ну вот и всё, последний день отпуска подошел к концу. Завтра — полёт обратно в Тюмень. В этом посте поделюсь впечатлениями, и кому-то наверняка полезными замечаниями.

Отдых — это извечная проблема. Казалось бы, можно отдыхать, не работать, не думать, но для меня практически всегда это заканчивается муками о том, а что же делать тогда? В эту поездку мы решили, что постараемся просто не думать о работе, будем гулять, наслаждаться заведениями в городе, который уже более-менее знаком.

Чтож, задача выполнена, но получили ли мы от этого удовлетворение? Ксюша — точно, а вот я пока что не определился. Есть ощущение, что я воспринял задачу слишком буквально. Да, я вообще не думал о работе, чему нельзя не радоваться, но не переборщил ли я с прогулками?

У нас в семье выносливой в контексте прогулок считается Ксюша, а вот я — домосед, коих ещё поискать. Я не люблю долгие прогулки, потому что после них болят ноги и нет сил. Но ведь это отпуск, и надо что-то делать?

Ну так вот, за 6 дней в Питере, я нагулял 95.000 шагов. Самый внушительный день — 22.000 шагов. В этот день мы с Тимуром (Baremantar, модератор канала) встретились, гуляли, болтали на разные темы. Ну и мне понравилось, к слову.

Что мне не понравилось, так это то, что я пишу этот пост, и чувствую переутомление. Кажется, что вот такая резкая длительная нагрузка приводит к тому, что максимальный запас выносливости с каждым днем снижается, а заканчивается всё тем, что появляется сонливость.

Вот вам инсайт — если вы видите себя во мне, то учтите, что постоянно тарабанить свой организм подобными нагрузками может оказаться не лучшей идеей. Что самое неприятное — оно приходит незаметно. Под конец дня ты чувствуешь, что хорошо погулял, устал, и крепко поспишь. А вот под конец недели можешь словить неприятные ощущения.

Поездку, в целом, считаю полезной. Конечно, с полноценным отпуском в какой-нибудь Турции это не сравнивтся, но к этому вопросы мы вернёмся летом.

———

Стрим не раньше второй половины недели. Меня не было, а задачи копились. Нужно будет хорошенько поработать, а потом буду более-менее свободен 😅
Please open Telegram to view this post
VIEW IN TELEGRAM
10👍43👏1
Как вы уже успели понять, я решил своеобразно продолжить свой отпуск, приостановив всё, что можно, кроме работы. Частично это потому, что в моём балконе-аквариуме сидеть в такую жару (+30), а уж тем более стримить, просто невозможно. Решение проблемы в процессе.

Несмотря на это, у меня появилось желание рассказать о боли, с которой столкнулся недавно.

😐 Об оценке задач

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

Моя практика говорит о том, что если задача по ощущениям слишком большая, то её надо разбивать на несколько других, то есть декомпозировать. Так принято практически во всех организациях, где я успел побывать. Условно, если какой-то функицонал требует более 2-ух дней на реализацию, то она должна состоять из нескольких задач. Понятно, что не нужно уходить в какое-то экстремальное декомпозирование, но и слишком обобщённые задачи заводить не стоит.

Сейчас я работаю в небольшой команде, и по этой причине к оценке задач мы подходим чуть проще. Когда меня просят оценить разработку какого-то интерфейса, я просто смотрю на него пару минут, и говорю "Думаю, дня 2. Максимум 3". Интерфейс выглядит достаточно простым. Кажется, что реализовать его будет несложно.

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

Ну и в общем, я понял, что недостаточно ответственно подхожу к оценке задач, и для решения проблемы решил, что надо бы с этим что-то сделать. Теперь я воспринимаю оценку реализации функционала как полноценную, совсем небольшую задачу. Конечно, я сюда не включаю такие случаи, которые требуют полноценного RnD (Research and Development), а лишь сравнительно небольшие.

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

И ведь не так сложно, не правда-ли? А всё лишь из-за того, что отвык от работы в больших компаниях.

———

Стрим будет как только так сразу. Мне хочется потрогать Tailwind на предмет того, что полезного я могу оттуда извлечь. Я мало чего знаю про эту технологию, но уверен, что Tailwind — это далеко не только море подготовленных classname-ов. О том, как я хочу его использовать у себя, расскажу уже на стриме 👨‍💻
Please open Telegram to view this post
VIEW IN TELEGRAM
944💯1
📱 Guest mode в Telegram Bots

Как-то совсем незаметно для меня появилась интересная фича в ботах Telegram, именуемая Guest Bots.

Если говорить кратко, то это альтернатива inline mode-у, который в Telegram уже достаточно давно.

Давайте кратко про оба режима.

🥺 Inline mode

Inline mode позволяет пользователям начать своё сообщение с наименования бота и каким-то кастомным вводом.

Пример (будет искать gif-ку танцующего медведя):
@gif dancing bear


В ответ на это, сервер бота @gif, обрабатывающий события от сервера Telegram, получает событие об inline-вводе, на что может чем-либо ответить. Как результат, у пользователя тут же в рамках ввода можно выбрать какие-либо опции для отправки сообщения в чат.

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

☺️ Guest mode

Guest mode работает аналогично — вы указываете наименование бота, а далее пишете какой-то текст. Вот только при этом никакие опции вам в ответ не предлагаются.

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

Рабочий пример:
@mira каковы шансы, что под этим постом напишет лично Павел Дуров?


Использовать ботов, которые включили Guest mode можно где угодно — в переписке с другом, в школьном / студенческом чате, хоть в комментариях под каким-нибудь постом. Бот ответит прямо там, и ответ будет виден всем, кто в этом чате присутствует 😏

Всё зависит от того, как бот обрабатывает такие запросы, а также от вашей фантазии.

🤌 Про @mira

В качестве примера, @mira я привёл не зря. Это пока что единственный AI-бот в моей жизни, которым я реально пользуюсь. Самые внимательные могли заметить Миру в анонсах Telegram, а также в некоторых сообщениях Павла в Твиттере (я там не сижу, мне показали, клянусь).

Как пример использования, могу привести рабочий. Мира подключена к рабочему Linear (Jira на минималках). Периодически мне необходимо отчитываться о проделанной работе и предоставлять summary из N пунктов по определенному формату. Я просто иду в чат с @mira и пишу что-то вроде "Выдай мне список из N задач, которые я выполнил за M промежуток. Выдели самые ценные с точки зрения бизнеса задачи, и в краткой форме, на английском языке, создай список". Мира сама просачивается в Linear, и мне не приходится выполнять эту задачу ручками. А я очень не хочу.

Говорят, что в Мире можно как-то скиллы делать, и не нужно постоянно ей этот запрос писать, но я пока не добрался. До меня как обычно, всё приходит с задержкой. Когда-нибудь точно освою. Ну или визуальный интерфейс под это подходящий сделают.
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🤔31🔥1
Передаю привет разработчикам из ЖизньМарта
😁17😭11
Чисто случайно открыл devtools в linkedin, и обнаружил вот такую картину — в консоль пишется какое-то нереальное количество ошибок отправки запроса со странным URL, а корнем всех ошибок является одна и та же строчка.

Решил разобраться, и понять, в чём там дело, и как выяснилось, linkedin вот таким образом сканирует пользователя на наличие установленных расширений браузера. Чтобы вы понимали, там список из 4680 расширений. Для каждого, судя по всему, описан файл, который специфичен для расширения, и который нужно запрашивать.

Пока что не понимаю, как к этому относиться, но скорее негативно. Какого фига вообще linkedin нужно знать, какие расширения у меня стоят? Ещё и список такой сумасшедший, что больше это походит на какой-то шпионаж за пользователем.

P.S. Выгрузил пары { id, file } расширений в комментариях, может кто захочет посмотреть, какие расширения трекает linkedin. Посмотреть, что за расширение, можно в магазине Chrome по шаблону ("abc" можно не трогать):
https://chromewebstore.google.com/detail/abc/{id}
🤯14🥴2
Вчера я почти собрался с мыслями и включил трансляцию, но из-за того, что с работой закончил слишком поздно, решил отложить. Посмотрим, будет сегодня стрим или нет, а пока прочитайте этот полезный пост 🤩

Анимации в веб-разработке

Как-то я уж совсем подзабыл про статьи чудесного Josh Comeau. Не так давно, в отдельной статье он сравнил анимации, основанные на CSS и JS, из чего удалось почерпнуть что-то полезное, и к этому мы ещё вернёмся. Несмотря на полезность статьи, там ещё есть что добавить, поэтому от себя я кое-что накидаю.

Почему вообще эта тема мне интересна? Я люблю делать красивые приложения, люблю делать приложения, которые не оставляют негативного послевкусия, люблю делать приложения, к которым хочется возвращаться.

Одним из факторов, которые приводят к тому, что пользователь возвращается, можно считать приятный на глаз интерфейс. Приятный не только функционально, но и визуально. Ну и тут, конечно же, без анимаций (а чаще переходов, transition-ов) не обойтись.

✍️ TLDR статьи Джоша

Чаще всего для разработки анимаций используются уже готовые библиотеки — GSAP и Motion. Иногда используют нативный requestAnimationFrame, в остальных случаях анимации, основанные на CSS.
Анимации на CSS выполняются в отдельном от главного потоке. Таким образом, анимации на JS с большей долей вероятности могут подтормаживать (если main thread обильно используется приложением).
У GSAP и Motion свои особенности работы, инструмент нужно подбирать исходя из требований.

😕 Анимации на CSS не всегда выполняются в Compositor Thread-е (Off Main Thread)

Интуитивно и правда казалось, что CSS-анимации должны выполняться как-то отдельно от того, что происходит в главном потоке, где мы исполняем JS. Как выяснилось, это не всегда так.

Я решил покопаться в том, как это устроено, и вот, что выяснил:

Определение потока для анимации основывается на том, какие свойства мы анимируем
Список свойств, которые могут анимироваться в Compositor Thread: transform, opacity, filter, backdrop-filter. То есть это те свойства, изменение которых не приводит к repaint / reflow.
Таким образом, свойствами, которые будут анимироваться в Main Thread, могут быть следующие: width, height, top, left, right, bottom, margin, padding и другие.

📱 Element.animate()

Вот о чём Джош не сказал, а наверное стоило бы, так это о нативном методе animate, который применяет анимацию на элементе:
myElement.animate(
{ opacity: [0, 0, 1] },
{ duration: 300, easing: 'ease-out' }
);


Возьмите этот метод на заметку, если ещё не, потому что лично я пользуюсь им достаточно часто. Определение потока в этом случае осуществляется по базовым признакам, которые описал выше.

🤓 Доступность

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

Для определения подобных пользователей, в CSS есть media query prefers-reduced-motion:
.animated {
// ... свойства для анимированного блока.

@media (prefers-reduced-motion: reduce) {
// ... свойства на случай, когда пользователь предпочитает
// меньше переходов на экране.
}
}


В JS можно использовать вот такой код:
const prefersReducedMotion = !!window.matchMedia("(prefers-reduced-motion: reduce)")?.matches;


Если говорить о ТМА, то мне неизвестно, работает там подобный код или нет. Но что-то подсказывает, что если и работает, то не на всех клиентах. Это ещё предстоит проверить.

———

Появилась идея написать побольше о том, как я реализую некоторые специфичные переходы в своих приложениях. Один из таких даже есть в админке Платформера. Но для этого придётся выделить отдельную статью.

Если есть какие-то замечания к статье — накидывайте. Мог что-то не так понять, или быть может вам есть что дополнить.

#css #js
Please open Telegram to view this post
VIEW IN TELEGRAM
25👍42
💬 Telegram выкатил обновление Markdown.. Но пока только для ботов

В Telegram Bot API 10.1, Команда выкатила обновление, которое значительно расширило возможности Markdown. Как человеку, который любит писать посты, нормального форматирования в мессенджере категорически сильно не хватало. И вот, наконец, закрыли одну из моих болей 😇

Жаль, конечно, что нельзя это форматирование использовать прямо вот так, в тексте использовать, но хорошо хоть есть пока что вариант делать это через бота. Буду думать, как применить.

Боже, ну вы только посмотрите на это чудо: @richtextdemobot

Подробнее об обновлении
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥112👍2
🙂 Да, я разрабатываю AI-проект в Telegram — @mira

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

И тут важно сразу сделать замечание, потому что уже не один раз происходила путаница — я разрабатываю только клиентскую часть Миры (мини-приложение, например), и всё прилегающее. За всё остальное (бота, бэк, AI) у нас отвечают другие ребята.

Примерно 9 месяцев назад началось это увлекательное путешествие, и вот, наконец, как девочка-подросток, я могу поделиться своим парнем могу поделиться тем, над чем работаю.

Ну а начну, пожалуй, с того, почему не рассказывал раньше. С моей точки зрения, работа в стартапах — затея неустойчивая. Всё может кончиться тем, что поработаешь 3 месяца, и стартап закроют по тем или иным причинам. А причин таковых, как водится, может быть достаточно много.

Второй причиной было то, что я не был удовлетворён качеством продукта. Периодически мне не совсем нравилось то качество, что выдаю я, в другие моменты не нравилось качество работы Миры как бота. Я просто ждал, когда мы выйдем на какое-то плато, о котором не стыдно рассказать, и сообщить о причастности. Если говорить о качестве продукта, который создавал я, то могу сказать, что преимущественно оно было снижено из-за первого продуктового опыта использования Vue, а также в принципе первого соприкосновения с Nuxt. На данный момент состоянием проекта я вполне удовлетворён, хоть и вижу пространство для улучшений.

В своих постах я уже упомянал Миру, но не из цели как-то прорекламировать, а из того, что действительно ей пользуюсь, хоть и не часто. На стримах я уже неоднократно говорил, что не особо тянусь к нейронным сетям, и привык делать всё самостоятельно, лишь изредка обращаясь за помощью. Но вот когда мне действительно становится лень что-то делать, или я понимаю, что могу без снижения качества выполнить свою задачу, обратиться к нейронкам для меня уже не составляет большой проблемы.

Напоследок скажу, что мы готовим обновление, которое позволит значительно когнитивно упростить использование Миры через само мини-приложение. В итоге даже такие, наверное, скептики, как я, смогут попробовать её функционал.

Ну и вот такие вот пироги. Для тех, кому интересно, вот приложение. Можете поизучать код, увидеть мои нотки, знакомые по стримам компоненты и прочее. Совсем недавно, как раз, мы выкатили обновление, которое сильно изменило визуал.

Ну и да, мы используем 👨‍💻 Платформер в разработке Миры, что уже не один раз экономило нам время.

P.S. В чате собралась личная QA-команда
Please open Telegram to view this post
VIEW IN TELEGRAM
1🔥1962
This media is not supported in your browser
VIEW IN TELEGRAM
2048 год. Закрылась последняя AI-компания, и теперь можно легко найти работу разработчиком ПО.

Только теперь ты не можешь использовать AI в разработке.
😁123❤‍🔥1
👩‍💻 Промежуточное заключение по Tailwind CSS

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

Давайте начнём с того, чем Tailwind может оказаться хорош.

✔️ Преимущества

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

Второе преимущество заключается в абстракции стилизации. Я не имею ввиду классы, типа flex, absolute и прочих, для которых есть однозначная проекция в CSS (display: flex, position: absolute), а классы формата mt-2, yb-3 и text-primary. Все такие классы скрывают за собой использование каких-то динамических значений, задаваемых из конфига, и в конечном итоге вам не придётся самостоятельно императивно ссылаться на такие значения, представленные в виде CSS-переменных. Таким образом, Tailwind абстрагирует использование динамических, конфигурируемых значений.

Третьим преимуществом, вероятно, можно считать ускорение выполнения задач в маленьких проектах. Пока что, в моём понимании, под маленькими проектами подразумеваются лендинги. Сами по себе они не воспринимаются как что-то большое. По этой причине не хотелось бы вкладывать много усилий, например, в то, чтобы создать какую-то дизайн-систему. Тогда на помощь приходит Tailwind со своей базой, которую можно сразу же использовать в разработке.

Сомнительные преимущества

На последней трансляции говорил, что посмотрел ещё одно видео от Fireship про Tailwind. Вот оно.

В видео, на самом деле, ничего шибко интересного нет, мне было интереснее почитать комментарии, потому что тема достаточно холиварная в сообществе frontend-разработчиков.

Так вот, озвучу ещё 2 преимущества, которые таковыми особо не считаю, но считают некоторые другие разработчики из комментариев.

Tailwind уменьшает размер CSS за счёт переиспользования классов, с уже описанными правилами. С одной стороны это правда, а с другой — есть предположение, что эффект будет не столь значительным. Важно помнить про то, что CSS, как и весь остальной контент, мы чаще всего не гоняем в открытом виде, а сжимаем при помощи алгоритмов сжатия. Таким образом, условный display: flex при появлении 2 и более раз, простыми словами, будет заменён на какую-то другую, заметно меньшую последовательность символов. Когда в CSS мы будем повторять display: flex, используя Tailwind, в HTML мы будем повторять flex. Таким образом, складывается ощущение, что меняем шило на мыло. Но в каких-то кейсах небольшой выхлоп наверняка будет.

Ну и второе, сомнительное с моей точки зрения преимущество — срез неиспользуемых классов. Когда в CSS мы объявляем какой-то класс, может оказаться так, что он нигде не используется. В Tailwind такое возможным не представляется, потому как классы используются сразу в HTML, а в бандл попадают только те, что используются. Считаю это преимущество слабоватым по той причине, что при компонетно-ориентированной разработке такой кейс просто невозможен. В том же Vue мы описываем классы прямо в компоненте (SFC). Если компонент где-то используется, его класс(-ы) попадёт в бандл.

Остальные комментарии под тем видео разбирать особо смысла нет, так как из-за уровня описываемых проблем, есть ощущение, что отписывались не самые опытные разработчики. Чаще всего они не понимают, что проблема не в CSS, а в них самих, в их подходе к разработке.

Недостатки

Недостатков, как бы это не казалось странным, не так уж и много. Пока что я вижу только один.

Первое, что бросается сразу всем в глаза — пугающих размеров атрибут class на HTML-элементах. Мне, как приверженцу BEM, на такое очень больно смотреть, а кроме эстетических недостатков есть ещё и практические.

1. Я абсолютно неспособен читать стили компонента по горизонтали. Tailwind именно это и делает, когда вынуждает разработчика описывать стили горкой классов, записанных по горизонтали. Очевидно, по-другому не выйдет. Чтобы было понятнее, для меня это как читать JS-код, в котором убрали переходы на следующую строку.

Накину тут ещё личных ощущений:

Чтение классов Tailwind по времени выполнения — это O(N), где N — количество символов, которое надо просмотреть, чтобы найти нужное правило. Простыми словами, чтобы найти нужное правило, мне придётся просмотреть вообще все стили. Всё оттого, что читать приходится по горизонтали.

Чтение правил в обычном CSS по времени выполнения — это O(M), где M — количество строк в классе, которое надо просмотреть, чтобы найти нужное правило. У меня нет необходимости просматривать всю строку до конца, чтобы понять, что она мне не подходит. Я могу просто опустить глаза ниже. А всё оттого, что код написан по вертикали.

В целом, это замечание подходит под абсолютно любой, написанный по горизонтали код.

2. При описании компонентов, Tailwind лишает вас возможности понять, какие модификаторы были применены. Представим, что есть компонент у которого есть какое-то свойство, принимающее одно из 5 возможных значений. Каждое из этих значений накладывает на компонент свой набор классов Tailwind. Открыв DOM, чтобы понять, какой модификатор (одно из значений того самого свойства) применился, придётся лезть в исходники и глядеть, какой из наборов классов подходит больше всего под текущий список. Интуитивно, в реальной разработке ситуация гораздо хуже из-за большего списка возможных применяемых модификаторов. Это катастрофически контр-продуктивно.

✏️ Заключение

Возвращаясь к видео, комментарии под которым разбирал выше, был очень рад увидеть разработчиков, которые догадались, что некоторые проблемы Tailwind закрывает тот самый BEM.

Говоря об описанных недостатках выше, BEM не является горкой из классов, но эту горку, при помощи инструментов Tailwind, можно упаковать в класс на BEM.
.button {
@apply text-red font-bold ...;
}


А что с модификаторами? Всё просто. Они буквально являются частью BEM. В HTML у элемента вы увидите какой-нибудь класс button--columned, сразу поняв, что то самое свойство из 5 возможных значений, приняло значение columned.

В общем, когда-нибудь попробую Tailwind, но не в ближайшее время. Сейчас пока что просто негде найти ему применение. Ну и использовать, конечно же, буду также под сопровождением методологии BEM.
Please open Telegram to view this post
VIEW IN TELEGRAM
2🔥1