Первая статья здесь Инженерия - это не дегустация. Нельзя так просто выписать плюсы и минусы, попробовать их на вкус и выбрать то, что больше нравится. Одна из главных задач хорошей архитектуры - обойти все грабли, и если наступить, то осознанно, с четким пониманием, что сейчас будет больно, но это лучшее решение среди остальных. В вопросе выбора инструмента, влияющего на архитектуру, я хочу точно понимать, какие грабли меня ожидают в будущем, готов ли я скакать по этим граблям, готов ли к этому заказчик проекта? Вопрос граблей стоит намного более остро, чем даже вопрос скорости и удобства разработки. По началу проект может развиваться быстро, но по мере его роста может оказаться, что небольшие изменения занимают неприемлемо много времени, и работа становится все более изматывающей. Люди почему-то считают объем работы только по времени ее выполнения, а то, как напрягаются мозги в это время, не учитывают. При продумывании хорошей архитектуры очень важен опыт создания и поддержки долгосрочных проектов. Только такой опыт позволяет наступить на все грабли и понять ошибки, заложенные в фундаменте проекта. В этой статье я поделюсь своими граблями. Если у кого-то есть что добавить к ним - пишите в комментарии. Разберем их все. Граблями я называю неожиданные сложности в решении простых, казалось бы, задач, которые значительно увеличивают время их выполнения или мозговые ресурсы. Важно отметить, что при написании этой статьи я опирался только на свой большой опыт разработки на Svelte. Пару лет назад я пытался прикрутить BEM к React, и мне не удалось это сделать, что меня сильно удивило. Там не было возможностей это сделать так, чтобы и изоляция стилей работала, и можно было менять стили из родительского компонента не ломая все остальные компоненты, и стили были в виде CSS, и классы в HTML можно было указать просто текстом, ровно в таком же виде как и в CSS. На Svelte все это делать легко, там практически пишешь обычный HTML + CSS, потом разбавляешь его логикой, а Svelte делает всю магию по гибкой изоляции стилей. Возможно в React и невозможно по-человечески использовать BEM, и Tailwind спасает ситуацию со стилями, но большого опыта у меня в этом нет. 1.1. Общие для всех архитектур инструменты разработки: 1.1.1) PostCSS 1.1.2) Современный UI фреймворк: React / Vue / Svelte / ... 1.2. Архитектуры: 1.2.1) Ванильный CSS + BEM 1.2.2) Tailwind (православный) со стилями в HTML и без активного использования @apply 1.3. Возможные задачи: 1.3.1) сверстать все страницы с нуля 1.3.2) создать несколько компонентов с разной внутренней логикой, но с очень похожим стилем 1.3.3) создать несколько компонентов с той же логикой, но с небольшими изменениями в стиле 1.3.4) создать несколько страниц с небольшими изменениями в стилях некоторых элементов 1.3.5) создать темы оформления с как можно большими возможностями в изменении стилей элементов 1.3.6) точечные исправления/изменения в верстке 1.3.7) изменить стиль элементов определенной категории 1.4. Возможные изменения в элементах: 1.4.1) изменить все мелкие отступы, цвета, шрифты 1.4.2) скрыть пару элементов 1.4.3) стилизовать некоторые элементы по-другому 1.4.4) поменять градиент или картинку 1.5. Влияющие факторы: 1.5.1) весь проект со строгим гайдлайном 1.5.2) весь проект без строгого гайдлайна 1.5.3) требование Pixel Perfect 1.5.4) 1-2 разработчика на проекте 1.5.5) на проекте несколько человек или большая команда 1.5.6) простой одностраничный сайт или лэндинг 1.5.7) большой сайт 1.5.8) фиксированный проект без будущих изменений 1.5.9) непредсказуемость развития, т.е нельзя заранее сказать, какие изменения и в каких элементах могут произойти. Могут быть только общие предсказания, типа отсутствия тем оформления. Будем искать оптимальные способы решения задач для всех архитектур, с учетом дополнительных влияющих факторов. Если весь проект со строгим гайдлайном, то проще будет работать с Tailwind. Если нет строгого гайдлайна, то его можно сделать строгим и верстать примерно. При верстке по макету из Figma без строгого гайдлайна проще копировать чистый CSS, чем подбирать классы Tailwind на глаз и по памяти. Pixel Perfect легче делать на ванильном CSS, так как DevTools позволяет легко подгонять размеры и отступы, а затем копировать CSS в код. Если над проектом работают несколько человек, то при использовании Tailwind им не нужно разбираться в общих CSS-классах других разработчиков. Общие классы в этом случае сложнее изменять, что будет время от времени происходить в ходе разработки. Для Tailwind нужно создавать компоненты без общих стилей. Такое легко создать, но сложно менять, если компонентов много. На ванильном CSS можно сделать общие стили и переиспользовать их в разных компонентах. Такие стили легко менять сразу для всех компонентов. В Tailwind изменения в стилях нужно интегрировать в логику, меняя классы в HTML в зависимости от параметров. Параметр компонента - это как модификатор в BEM. Я боюсь представить во что превратиться компонент, если у него будет много различных модификаторов, вносимые изменения которых раскиданы по всему HTML. Ванильный CSS хорошо справляется с этим. Можно менять стиль компонента так же через параметры, но подменяя в коде только один BEM-класс модификатор для контейнера. А стиль модификатора настраивать отдельно в одном месте. Кроме того, ванильный CSS позволяет изменять стили вложенных компонентов без изменения кода этих компонентов. Многие стили можно менять через CSS-переменные. Возможности Tailwind здесь ограничены. Чтобы точно указать, какие стили каких элементов можно менять через переменные, придется использовать ванильный CSS. В Tailwind придется прописать классы с уникальными именами для каждого изменяемого элемента и использовать ванильный CSS для их модификации извне. Если использовать BEM, то все имена элементов уже прописаны, так что для создания новой страницы с немного другим стилем не придется менять вложенные компоненты. Достаточно написать CSS изменяемых стилей в одном месте в корневом компоненте страницы. Tailwind дает ограниченные возможности в создании тем оформления. Если менять что-то, то сразу все на странице: все цвета, все отступы. CSS-переменные внедрять тоже проблематично без ванильного CSS. Создавать классы-утилиты с CSS-переменными можно только глобально, а не для конкретного компонента. Ванильный CSS имеет огромные возможности как в использовании CSS-переменных, так и в точечных изменениях любых свойств элементов. Если используется BEM, то очень просто изменить стиль отдельного элемента или элементов определенного вида, находящихся в определенном месте. Но для изменения всех цветов на сайте или всех отступов придется заранее прописывать все CSS-переменные и распространять их по всему коду. В Tailwind все эти переменные уже прописаны. Элементы Tailwind сложно искать. Нельзя так просто по атрибуту class узнать, в каком месте проекта находится соответствующий код. Еще хуже, если таких мест несколько и нужно изменить их все. Сложно также понять, какую роль играет определенный элемент в коде: это контейнер, обертка, независимый блок и т.д. Рефакторинг из-за этого крайне затруднен. Закон Миллера говорит о том, что человек может удерживать во внимании одновременно 5-7 сущностей. Чтобы распознать роль определенного элемента, разработчик должен заполнить весь свой "кошелек внимания", т.к. нужно проанализировать все классы элемента, чтобы понять его роль. Еще сложнее, когда в коде несколько элементов с одной ролью и нужно найти их все. Элементы BEM искать очень легко, если, конечно, BEM-классы написаны в CSS в таком же виде, как в HTML. Нужно просто скопировать имя класса и найти его в проекте. Очень легко найти все места, где этот класс используется. Чтобы изменить стиль нескольких элементов одного вида, нужно отредактировать только один стиль, если, конечно, в верстке соблюдена хоть какая-то структура. А BEM заставляет разработчика думать о структуре верстки. Очень легко по названию класса понять, какую роль имеет элемент. Рефакторить такой код не сложно. "Кошелек Миллера" может вмещать сразу несколько элементов. Также легко поиском найти в файле все элементы с определенной ролью. Очень сложно в Tailwind изменить стиль элементов определенной категории, так как Tailwind не предполагает продумывание структуры верстки. Нет структуры - ищи все вручную. Если элементов много, придется каждый искать вручную. BEM заставляет продумывать структуру верстки. Поэтому искать элементы определенной категории можно простым поиском по именам классов. 3.1) Сверстать все страницы с нуля Нет строгого гайдлайна + Pixel Perfect => строго ванильный CSS Есть строгий гайдлайн => Tailwind будет удобнее 3.2) Создать несколько компонентов с разной внутренней логикой, но с очень похожим стилем Большой разницы нет 3.3) Создать несколько компонентов с той же логикой, но с небольшими изменениями в стиле Tailwind здесь имеет сильные ограничения и заставляет стиль компонента смешивать с другой логикой Ванильный CSS в этом плане очень гибкий 3.4) Создать несколько страниц с небольшими изменениями в стилях некоторых элементов Tailwind использовать нельзя, только ванильный CSS 3.5) Создать темы оформления с как можно большими возможностями в изменении стилей элементов Tailwind можно использовать для тем оформления, но с большими ограничениями Ванильный CSS практически не имеет ограничений на темы оформления 3.6) Точечные исправления/изменения в верстке Tailwind сложно читать и редактировать. При использовании BEM и именовании всех элементов искать их очень легко, а если в HTML не писать Tailwind-классы, то ориентироваться по коду еще легче. 3.7) Изменить стиль элементов определенной категории В Tailwind верстке это делать очень сложно, особенно если элементов много в разных частях сайта. BEM позволяет легко найти все элементы простым поиском по именам классов. В плане гибкости разработки Tailwind сильно уступает ванильному CSS + BEM. Некоторые считают, что BEM и Tailwind не противоречат друг другу. Да, их можно технически смешивать вместе, но это разные архитектуры. Смешивая их вместе, мы получаем как плюсы от обоих архитектур, так и минусы. Смешивание разных подходов может привести к тому, что код может превратиться в свалку. Такая смешанная архитектура должна быть хорошо продумана. Но я пока не видел НИ ОДНОЙ статьи по архитектуре Tailwind, чего уж говорить об архитектуре Tailwind + BEM. Зато полно статей по архитектуре для ванильного CSS. Пока я не понимаю, как на Tailwind решать задачи: 4, 5, 6, 7. Эти минусы Tailwind для меня критичны, а минусы BEM - нет. Пишите, если есть что сказать. Особенно интересно, как вы решаете задачи, которые я здесь описал, с помощью Tailwind. Может, я еще не знаю каких-то секретов разработки на Tailwind.