Комментарии 44
Когда ваши компоненты или не подлежат какой-то особой кастомизации, или подлежат, но количество контекстов очень маленькое — тогда с переменными работать можно, и теневой DOM даже в некотором смысле удобен. Но это не масштабируется совсем, и комбинаторный взрыв поджидает буквально за углом. Без ::part лично я бы не рискнул связываться с теневым DOM, если только у меня не будет полного контроля за контекстом использования моих компонентов; это имеет огромные шансы в будущем выродиться в десятки часов пустопорожней работы вида «а добавь нам переменную вот сюда».
PS: Кстати, касательно протечек — у переменных общий неймспейс, и если вы на второй сотне переменных добавите такую, имя которой уже где-то было, то немедленно получите те самые протечки ^_^
Я, какбэ, по долгу службы, специализируюсь именно на UI-либах и дизайн-системах. И вот я читаю, что вы пишите — и вообще не понимаю о чем вы.
Серьезно? Вы специализируетесь на UI-либах и дизайн-системах, и вам никто ни разу не говорил «вот у нас бутстрап, а у вас ваша либа, нам надо, чтоб бутстрап был натянут на ваши компоненты»?
Вы специализируетесь, но не понимаете, в чём тут беда, когда у вас на какую-нибудь кнопочку заведено 12 переменных (это я пересчитал, сколько стилей кнопочек у нас в проде перекрывается)? И что это нужно умножить на количество простых компонентов (которых, в самом деле, 50 не будет, но 20 — вполне)? И что потом для составного компонента из 5 простых задача на кастомизацию будет звучать как «выставите нужные значения для 12 * 5 переменных»? Вы такой css называете «без монструозных конструкций»? Я вам тут сразу скажу, что БЭМ, который никто не любит, и я тоже — в сравнении с портянками из переменных будет менее монструозным, а не наоборот.
Вы неправильно считаете: не по 12 переменных на кнопочку, а 12 переменных на всю вашу кухню должно хватить.
Эм, нет. По 12 переменных на каждый отдельный контекст, в котором кнопочка должна выглядеть по-своему. И по примерно 12*5 на, к примеру, особо выглядящее модальное окно (предположим, что product owner хочет совсем особо выглядящие модалки на ошибки, ворнинги, уведомления, итд).
То есть, разумеется, не по 12 новых переменных, а по 12 присваиваний значений. И этими портянками будет забит весь css.
Если у вас в КАЖДОМ примитиве разные переменные для отступов, скруглений, цветов, шрифтов и т.д.
«Ваш дизайн говно, вы ничего не понимаете в дизайне» (с) один очень хайповый дизайнер.
Наличие разных переменных в каждом примитиве — не означает, что в конечном дизайне сайта в каждом примитиве будет выставлен свой шрифт, отступы, и т.д. Это всего лишь означает возможность выставить свой шрифт и отступы в тех 2% случаев, которые таки на весь проект обязательно где-то найдутся. Потому что если отдельных переменных нет, и всё закрыто на замок теневого DOM — всё, с этим без дообъявления переменных вы таки ничего не сделаете.
На конкретном примере это выглядит примерно так:
1) Вы запилили вашу крутую либу примитивов;
2) На этих примитивах запиливаются составные компоненты. Допустим даже это делаете вы сами, и вы всё сделали максимально удобно для переменных. Например, памятуя о том, что кнопки в модалке могут потребоваться самой разной стилизации, вы не запаковали их в составной компонент и пишете примерно так:
<modal>
<div slot="buttons"><ваши кнопки></div>
</modal>
3) А затем кто-нибудь на стороне продукта говорит: слушай, я не хочу это всё каждый раз писать. У меня есть модалка для ошибок и модалка для всего остального, и ничего другого нет и не будет. Давайте вы для конкретно нас сделаете:
<modal-error></modal-error>
<modal-generic></modal-generic>
Круто, правда? Ну окей, конкретно для них вы взяли и сделали.
А потом на следующий день вам пишет продуктовый дизайнер: «слушай, у нас вот тут модальные диалоги на вашей либе, и мне вот прям страсть как нужно поменять в модальном диалоге для ошибки шрифт на кнопке ОК. Я тут пытаюсь поменять через переменную, но у меня шрифт меняется сразу на всех кнопках этой модалки, а мне это не надо!».
И вот примерно на этом месте к вам плавно придёт осознание того, что компоненты у вас разбиты одним образом, а вот стили — совершенно другим, и чтоб всё работало, вам надо сидеть и сводить одно с другим. Бонус — если компоненты из вашей либы собраны в комплексные компоненты не один раз, а несколько, и на каждом шаге более специализированную либу собирали разные люди.
Круто, правда?
Нет, не круто. Нужно так:
<my-modal error></my-modal>
Ну блин, серьезно, я даже не знаю как такое прокомментировать… Стрелять себе в ногу — это особое искусство.
То есть, разумеется, не по 12 новых переменных, а по 12 присваиваний значений.
Верно. И количество этих присваиваний равно количеству конкретных контекстов, где это требуется, а вовсе не компонентов. А контекстов у вас, во первых, не может быть настолько много, а во вторых, на данном уровне, это уже ничем практически не отличается от стилизации классическими методами.
А контекстов у вас, во первых, не может быть настолько много
Очень смешно.
это уже ничем практически не отличается от стилизации классическими методами
Ну уж нет. Если вы пишете в блокноте — да, разницы мало. Если вы пишете в нормальной среде, то на стилизацию классическими методами у вас будет какая-то проверка синтаксиса, а на переменные не будет ничего. Да и потом в браузере — на каждый случай «не работает» вам придётся посмотреть, не ошиблись ли вы в названии переменной и не запутались ли в именах (и не, например, передаете какое-то неожиданное значение в стиль).
Очень смешно.
Если у вас количество контекстов использования, требующих отдельной стилизации, соперничает с количеством компонентов включая прмитивы — это действительно смешно.
а на переменные не будет ничего
Конкретно я юзаю VS Code чаще всего. Как-то не заметил особых проблем. Однако, тут вы поднимаете другую проблему, о которой изначально не говорили. Да, очепятки, наверное, возможны, как и в практически в любых других селекторах.
Я, какбэ, по долгу службы, специализируюсь именно на UI-либах и дизайн-системах.
Поэтому с упомянутой проблемой вы и не сталкиваетесь. С ней сталкиваются пользователи ваших UI-либ и дизайн-систем.
PS: Кстати, касательно протечек — у переменных общий неймспейс, и если вы на второй сотне переменных добавите такую, имя которой уже где-то было, то немедленно получите те самые протечки ^_^
Это не так. Точнее тут не совсем применимо слово «неймспейс», в CSS — каскады. И, как я уже написал, одна и та-же переменная может принимать разные значения в разных контекстах, заданных родителем элемента. Но сам набор этих общих переменных — конечно должен быть стандартизирован в рамках проекта.
В литах тормозить точно нечему, насчёт всего остального, что там еще в обвязке — не знаю.
Линяйте на $mol, тут всё летает, а прикручивание сервис-воркера — вообще одна строчка кода. Добавить манифест и получается PWA.
Можно подумать в Реакте нет толстых стрелочек.
И с вью и стейтом так же. Другое дело, что тысячи всяких туториалов и прочих «давайте сделаем to do list» мешают всё в кучу, а потом народ это всё читает, и пишет так же на проде.
ООП учило, что компонент должен быть самодостаточным и живучим — и данными своими управлять, и уметь себя презентовать разными способами, то есть инкапсулировать в себе самом модель и вью.
Смотря что вы хотите получить на выходе. Концептуально нет никаких проблем собрать максимально заточенный под конкретный случай компонент. Это вот то самое банальное, что вы уже скорее всего не раз видели:
<html>
<body>
<my-app></my-app>
</body>
</html>
Всё максимально самодостаточно. Может копать, а может не копать. То есть, работать или не работать.
Но тут внезапно к вам приходит второй клиент, допустим Вася, и говорит, что то, что вы сделали — это круто и здорово, только вот ему от этого нужно вот это, это, и еще вот то. А всё остальное — не нужно, но нужно новое, специально для Васи. Вы, конечно, можете почесать в голове, и воспользоваться сильнейшими средствами разработки под названием ctrl+c, ctrl+v, и через некоторое время сделать <vasya-app>. Потом вы обнаружите, что правки, которые вы делаете в одном месте относительно функционала, который есть и у Васи — вам нужно копировать в два места. Потом к вам придут еще Петя и Вова, и у вас скорее всего начнёт появляться мысль о том, что самодостаточность компонента не может быть самоцелью.
Ну и вообще говоря, SOLID не зря придумали и даже иногда на собеседованиях спрашивают. И ООП всё ж таки не учит тому, что нужно всё-всё в компонент заворачивать. ООП позволяет так сделать, но вот «можно» и «нужно» — это две большие разницы.
PS: А если вернуться к интерфейсам, то «как нужно» вам подскажут все эти MVC, MVP, и MVVM. Это практически один и тот же паттерн, повторяемый немного на разные лады (меньше чистоты — меньше бойлерплейта и наоборот). Лучше этого для дела проектирования интерфейсов до сих пор никто ничего в общем-то и не придумал.
Самодостаточность и нерасширяемость — тоже две большие разницы. Например, все компоненты в $mol самодостаточные и могут использоваться именно, как вы описали:
<html>
<body mol_view_root="$mol_check_box">
<!-- ага, тут будет работающий чекбокс -->
</body>
</html>
Но при этом вы всегда можете настроить его под конкретный контекст использования:
$my_app $mol_view sub /
<= Toggle_lights $mol_check_box
title \lights
checked?val <=> lights_enabled?val true
Самодостаточность и нерасширяемость — тоже две большие разницы.
Это вообще ортогонально моему комментарию выше. Я пишу про то, что в общем виде на вопросы «насколько самодостаточно» и «насколько расширяемо» ответ возможен только один — «насколько вам в рамках вашей задачи нужно».
А я про то, что одно вообще никак не исключает другое и даже можно получить обе характеристики максимальными по умолчанию.
Совмещать самостоятельность с расширяемостью до некоторой степени можно, а вот максимизировать и то, и другое — не очень.
Это было не сложно:
https://github.com/eigenmethod/mol/tree/master/check/group
От чекбокса ожидаешь, что он будет переключать стейт по клику и уметь в get/set, а у вас group определенную (и нужную) задачу конечно же решает, но гораздо более конкретную.
Это другой компонент с перекрытой логикой базового компонента
Это и называется расширение.
насколько я вижу, нет собственного стейта, и без других чекбоксов оно просто работать не сможет
Не придирайтесь, логику там можно написать любую. Просто не хочется реализовывать бесполезный компонент.
хотя вообще-то нет никакой причины, почему трехпозиционный чекбокс не может быть сам по себе (скажем, в роли переключателя true / false / not set)
Нет никакой причины использовать такой псевдочекбокс вместо собственно переключателя, который проще и понятней в использовании.
Что можно и нельзя выжать из веб-компонентов