react-redux-starter-kit
react-redux-starter-kit copied to clipboard
Css modules
В свете последних событий по поводу cssinjs есть пропозал опционального перехода на css-modules - опционально - потому что не на всех размерах проектов есть смысл изолировать стили.
Предлагается юзать изолированные css-modules в связке с типизацией через https://github.com/olegstepura/typed-css-modules-loader.
Предлагаю тему на ресерч - сложность реализации, использования и профиты по сравнению с обычным глобальным css.
P.s. типизация css-module возникает только когда применяется сама изоляция через css-modules.
может на вскод какое-нибудь расширение есть для генерации всего этого на лету? можно же в тсконфиге выставить флаг чтобы он не продалбывал типы при импорте json-файла. Может что-то подобное можно замутить с помощью расширения.
Ну это как фичу можно конечно-же) но я так понял в данный момент это возможно вебпаком на жтапе сборки стилей, насколько удобно - надо тестить )мне идея понравилась, Кирилл жаловался просто, что типы с классами пропадают и больше шанс ошибки, это ошибок шанс снижает )
Меня на тему борьбы с глобальностью CSS-a всегда одна вещь смущала: глобальность CSS-а в какой-то степени нас заставляет для новой сущности каждый раз придумывать свое уникальное имя. Т.е. когда в системе есть несколько сущностей, а имя у них одно и то же, имхо, такого быть не должно в принципе, это будет лишний раз путаницу вводить. Ну типа неймспейс в рамках блока у нас уже есть, а в рамках всего проекта делать уникальные имена - не знаю, хорошая ли это идея, потому что иметь 2+ блока с одним именем - не очень как-то. Хотя интуитивно, конечно, может быть дискомфорт чисто от того, что все классы глобальные и риск коллизий есть, поэтому я сам не уверен во всем что написал на 100%.
Ну да, на этапе сборки нужна проверка, но мне кажется важнее удобство разработки. С обычными стилями вообще никакой связи нет, мы пишем отдельно scss, отдельно вызовы бем-сн с элементами.
Еще один возможный путь решения, который будет одновременно и в вскоде работать и на этапе сборки - это tslint, возможно получится написать на него какой-нибудь плагин, который будет проверять импорты из стилей.
tslint - это про кодстайл, он здесь совсем не при чем)
У глобального css помимо прочего есть ряд проблем вроде коллизий с библиотечными стилями, хотя это решается чреез префиксирование. Ну большинство проблем - не столь реальны и актуальны, как кажутся, но имеются
Меня интересует типизация и снижении ошибок при расстановке классов. Надо это решить, есть решение, но оно сайдэффектит css-модулями ))
@chmnkh почти на всех проектах, на которых я работал такие коллизии случались)) Да это не часто бывает, но всё же бывает) Идеология бэма предполагает что каждый блок в плане стилей должен быть уникален и без css-модулей за этой уникальностью ты должен следить сам, а с ними ты можешь расслабиться и не думать об этом.
В целом мы все также можем использовать бэм и с модулями, просто вместо фактических строк ты вставляешь переменные, а используешь все точно также.
@NikitaRzm да, tslint - это про кодстайл, но его можно расширить плагином и пусть еще следит за наличием классов в стилях (хотя хз возможно ли это), я не говорю про автодополнения и прочее, пусть хотя бы предупредит что используемый класс не объявлен в стилях.
за этой уникальностью ты должен следить сам, а с ними ты можешь расслабиться и не думать об этом.
Ну да, меня здесь смущало, что если не придется самим за этим следить, то могут всякие дублирования рекой политься.
Вообще говоря, я не сразу вот о чем подумал: если учесть что чувак на проекте не один и его код все таки другие люди смотрят, тогда мой аргумент в общем-то ни о чем)
Я думал смысл юзать бэм отпадает, если юзаем css модули) вообще мне нравится тема, я погуглил, можно попробовать
Ага, бэм полезен только как пример для некоторого подражания остаётся юзать, напрямую в проекте он больше не нужен
ну можно было бы модификаторы бэмовские оставить, например, ибо они имхо прям хороши именование типа блок__элемент то уже смысла не имеет, и стили так опрятнее будут в принципе
бэм помогает еще в целом структуру кода локальную организовать ведь ) читать легче и писать быстрее иногда )
Вот еще один лоадер https://github.com/Jimdo/typings-for-css-modules-loader, но он походу заброшенный
а вот eslint плагин, хз будет ли он работать с тайпскриптом, но если что можно адаптировать под ТС. https://github.com/atfzl/eslint-plugin-css-modules
Он еще и проверяет css на неиспользуемые классы
попробую в кучу плюсы и минусы собрать навскидку плюсы:
- типизация
- бэм-цн можно будет на помойку выбросить в принципе то, что у нас в класснейм будут строки подставляться, а не какие-то мутные функции со свойствами, нас избавит от некоторых проблем, типа таких, что приходится в некоторых местах (например если мы в mui-компоненты свои классы суём и помощью бем-цн) в ручную вызывать toString на бем-цн "функции", т.е. вот так вот делать:
className={b('eto-dich').toString()}
в муи компонентах так приходится писать, потому что там под капотом юзается classnames, который не может переварить функцию b('eto-dich')
и вываливает в класснейм всякую чушь. b('eto-dich')()
тоже нельзя написать, потому что в типах для b('eto-dich')
сигнатуры вызова нету и это как будто бы объект, и тайпскрипт нам по шапке бьет за попытку его вызова. Не исключено, что кроме муи это еще где-то может за одно место укусить. Не то чтобы это прямо критично, но не очень приятно.
3) коллизий стилей не будет
4) таки удобно в тестах, например, написать
component.find(`.${styles.abc}`)
а не лезти в компонент и не смотреть как там класс написан. Да и вообще таким образом классы будут из одного источника исходить.
минусы:
- если нам где-то нужно заселектить элемент четко по строке с классом - моментальный крах из-за уникальных классов (Серега рассказывал, что им это в аналитике на птичке мешало; Влад рассказывал, что тоже в тестах на селениуме тоже надо было селектить по классам, в итоге какими-то костылями разрулили)
- Сереге чото там конкатенировать неудобно было, хотя я в целом не понял проблемы, ибо можно classnames юзать и должно быть ок
я так понял в целом @Znack не супер ЗА цсс-модули, поэтому он мб прояснит чего
По поводу аналитики и интеграционных тестов, где-то читал, что нормальной практикой является добавление дополнительного data-атрибута на ключевых элементах, по которому можно заселектить элемент или понять че это за элемент.
Но хз можно ли добавить дополнительный атрибут в тип html-элементов, чтобы тайпскрипт на нас не орал.
Это просто очень больно будет — на все элементы вешать отдельные атрибуты. Хотя это действительно практика получше, чем селекты по классу, так как с классами маркетологи жёстко завязываются на разработчиков, и вторые постоянно забывают про первых и меняют классы :)
Ага, еще ништяк, когда ты смотришь в верстку, то видишь все ключевые элементы, и внося правки ты понимаешь что и где может отвалиться.
У нас вроде даже где-то в стандартах был такой пунктик (not SPA), что если мы по классу привязываем какие-то обработчики к элементам, то нужно добавлять класс с префиксом js-
, и по нему делать такую привязку. Тут мне кажется очень похожая ситуация.
Вот еще наткнулся на довольно крутой подход к написанию стилей
Тут доклад, немного теории по теме и небольшая презентация этого решения.
Основные плюсы на мой взгляд:
- очень близко к нативному написанию стилей, за исключением некоторых деталей
- изолированные стили
- верстка получается очень чистой и семантичной
- стимулирует использовать семантичные теги
- есть динамические стили, не как в jss за счет потери производительности, а на основе css-переменных
- бенчмарк в огнях :) Для наглядности, я форкнул оригинальный бенчмарк и добавил туда отрисовку с использованием нативного css.
Из минусов:
- альфа версия, не большое комьюнити
- пока хз че с ssr
- есть рантайм, но он вроде как минимален
@chmnkh @Znack @clicktronix @NikitaRzm @kinda-neat что скажете?
Это получается, стиль написания внутри js - но экстрактится на этапе сборки в статику? Выглядит прикольно довольно таки конечно. Можно поресерчить - я так глянул в общем - вроде все что надо есть. Надо детально смотреть.
P.S. Когда заходишь на страницу технологии применения css - не ожидаешь что страница поедет этим самым css в последнем сафари :D

Не обязательно в js, можно писать в css и даже пропустить его через PostCSS. Если нужны динамические стили от пропсов, то можно писать в стиле CSS-in-JS (и похоже не обязательно это делать в js файле, но это не точно).
Но в итоге, весь css код попадает в js бандл и также инжектится при старте приложения как в любой CSS-in-JS библиотеке.
вот ишу у них нашел. Beta roadmap. Судя по ней всё готово к бете, осталось только документацию и экзамплы написать.
Тогда можно подождать, пока они закончат - и садиться изучать и пробовать применить на демке если все ок
@in19farkt про написание стилей все верно, можно писать стиле как эксклюзивно в отдельных css файлах как в стандартном подходе с css-modules, так и в js файлах как те же styled-components
. Если подключен reshadow webpack loader то стили будут доставаться из js файлов во время сборки и не будут раздувать js бандлы и инлайниться в хэд при инициализации приложения.
Подход с написанием стилей в js файлов удобен только в двух случаях
- разработчик уже привык к интерфейсу
css-in-js
решений - необходимость в runtime переменных
PS: спасибо за багу в сафари на стойте документации, в ближайшее время пофксим =)