fullstack-development / react-redux-starter-kit

Modular starter kit for React+Redux+React Router projects.
https://demo.fullstack-development.com/
MIT License
91 stars 13 forks source link

Css modules #64

Open NikitaRzm opened 5 years ago

NikitaRzm commented 5 years ago

В свете последних событий по поводу cssinjs есть пропозал опционального перехода на css-modules - опционально - потому что не на всех размерах проектов есть смысл изолировать стили.

Предлагается юзать изолированные css-modules в связке с типизацией через https://github.com/olegstepura/typed-css-modules-loader.

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

P.s. типизация css-module возникает только когда применяется сама изоляция через css-modules.

in19farkt commented 5 years ago

может на вскод какое-нибудь расширение есть для генерации всего этого на лету? можно же в тсконфиге выставить флаг чтобы он не продалбывал типы при импорте json-файла. Может что-то подобное можно замутить с помощью расширения.

NikitaRzm commented 5 years ago

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

chmnkh commented 5 years ago

Меня на тему борьбы с глобальностью CSS-a всегда одна вещь смущала: глобальность CSS-а в какой-то степени нас заставляет для новой сущности каждый раз придумывать свое уникальное имя. Т.е. когда в системе есть несколько сущностей, а имя у них одно и то же, имхо, такого быть не должно в принципе, это будет лишний раз путаницу вводить. Ну типа неймспейс в рамках блока у нас уже есть, а в рамках всего проекта делать уникальные имена - не знаю, хорошая ли это идея, потому что иметь 2+ блока с одним именем - не очень как-то. Хотя интуитивно, конечно, может быть дискомфорт чисто от того, что все классы глобальные и риск коллизий есть, поэтому я сам не уверен во всем что написал на 100%.

in19farkt commented 5 years ago

Ну да, на этапе сборки нужна проверка, но мне кажется важнее удобство разработки. С обычными стилями вообще никакой связи нет, мы пишем отдельно scss, отдельно вызовы бем-сн с элементами.

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

NikitaRzm commented 5 years ago

tslint - это про кодстайл, он здесь совсем не при чем)

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

Меня интересует типизация и снижении ошибок при расстановке классов. Надо это решить, есть решение, но оно сайдэффектит css-модулями ))

in19farkt commented 5 years ago

@chmnkh почти на всех проектах, на которых я работал такие коллизии случались)) Да это не часто бывает, но всё же бывает) Идеология бэма предполагает что каждый блок в плане стилей должен быть уникален и без css-модулей за этой уникальностью ты должен следить сам, а с ними ты можешь расслабиться и не думать об этом.

NikitaRzm commented 5 years ago

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

in19farkt commented 5 years ago

@NikitaRzm да, tslint - это про кодстайл, но его можно расширить плагином и пусть еще следит за наличием классов в стилях (хотя хз возможно ли это), я не говорю про автодополнения и прочее, пусть хотя бы предупредит что используемый класс не объявлен в стилях.

chmnkh commented 5 years ago

за этой уникальностью ты должен следить сам, а с ними ты можешь расслабиться и не думать об этом.

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

Вообще говоря, я не сразу вот о чем подумал: если учесть что чувак на проекте не один и его код все таки другие люди смотрят, тогда мой аргумент в общем-то ни о чем)

clicktronix commented 5 years ago

Я думал смысл юзать бэм отпадает, если юзаем css модули) вообще мне нравится тема, я погуглил, можно попробовать

Znack commented 5 years ago

Ага, бэм полезен только как пример для некоторого подражания остаётся юзать, напрямую в проекте он больше не нужен

chmnkh commented 5 years ago

ну можно было бы модификаторы бэмовские оставить, например, ибо они имхо прям хороши именование типа блок__элемент то уже смысла не имеет, и стили так опрятнее будут в принципе

NikitaRzm commented 5 years ago

бэм помогает еще в целом структуру кода локальную организовать ведь ) читать легче и писать быстрее иногда )

in19farkt commented 5 years ago

Вот еще один лоадер https://github.com/Jimdo/typings-for-css-modules-loader, но он походу заброшенный

in19farkt commented 5 years ago

а вот eslint плагин, хз будет ли он работать с тайпскриптом, но если что можно адаптировать под ТС. https://github.com/atfzl/eslint-plugin-css-modules

Он еще и проверяет css на неиспользуемые классы

chmnkh commented 5 years ago

попробую в кучу плюсы и минусы собрать навскидку плюсы: 1) типизация 2) бэм-цн можно будет на помойку выбросить в принципе то, что у нас в класснейм будут строки подставляться, а не какие-то мутные функции со свойствами, нас избавит от некоторых проблем, типа таких, что приходится в некоторых местах (например если мы в mui-компоненты свои классы суём и помощью бем-цн) в ручную вызывать toString на бем-цн "функции", т.е. вот так вот делать:

className={b('eto-dich').toString()}

в муи компонентах так приходится писать, потому что там под капотом юзается classnames, который не может переварить функцию b('eto-dich') и вываливает в класснейм всякую чушь. b('eto-dich')() тоже нельзя написать, потому что в типах для b('eto-dich') сигнатуры вызова нету и это как будто бы объект, и тайпскрипт нам по шапке бьет за попытку его вызова. Не исключено, что кроме муи это еще где-то может за одно место укусить. Не то чтобы это прямо критично, но не очень приятно. 3) коллизий стилей не будет 4) таки удобно в тестах, например, написать

component.find(`.${styles.abc}`)

а не лезти в компонент и не смотреть как там класс написан. Да и вообще таким образом классы будут из одного источника исходить.

минусы: 1) если нам где-то нужно заселектить элемент четко по строке с классом - моментальный крах из-за уникальных классов (Серега рассказывал, что им это в аналитике на птичке мешало; Влад рассказывал, что тоже в тестах на селениуме тоже надо было селектить по классам, в итоге какими-то костылями разрулили) 2) Сереге чото там конкатенировать неудобно было, хотя я в целом не понял проблемы, ибо можно classnames юзать и должно быть ок

я так понял в целом @Znack не супер ЗА цсс-модули, поэтому он мб прояснит чего

in19farkt commented 5 years ago

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

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

Znack commented 5 years ago

Это просто очень больно будет — на все элементы вешать отдельные атрибуты. Хотя это действительно практика получше, чем селекты по классу, так как с классами маркетологи жёстко завязываются на разработчиков, и вторые постоянно забывают про первых и меняют классы :)

in19farkt commented 5 years ago

Ага, еще ништяк, когда ты смотришь в верстку, то видишь все ключевые элементы, и внося правки ты понимаешь что и где может отвалиться.

У нас вроде даже где-то в стандартах был такой пунктик (not SPA), что если мы по классу привязываем какие-то обработчики к элементам, то нужно добавлять класс с префиксом js-, и по нему делать такую привязку. Тут мне кажется очень похожая ситуация.

in19farkt commented 5 years ago

Вот еще наткнулся на довольно крутой подход к написанию стилей

Тут доклад, немного теории по теме и небольшая презентация этого решения.

Основные плюсы на мой взгляд:

Из минусов:

@chmnkh @Znack @clicktronix @NikitaRzm @kinda-neat что скажете?

NikitaRzm commented 5 years ago

Это получается, стиль написания внутри  js - но экстрактится на этапе сборки в статику? Выглядит прикольно довольно таки конечно. Можно поресерчить - я так глянул в общем - вроде все что надо есть. Надо детально смотреть.

P.S. Когда заходишь на страницу технологии применения css - не ожидаешь что страница поедет этим самым css в последнем сафари :D

image
in19farkt commented 5 years ago

Не обязательно в js, можно писать в css и даже пропустить его через PostCSS. Если нужны динамические стили от пропсов, то можно писать в стиле CSS-in-JS (и похоже не обязательно это делать в js файле, но это не точно).

Но в итоге, весь css код попадает в js бандл и также инжектится при старте приложения как в любой CSS-in-JS библиотеке.

in19farkt commented 5 years ago

вот ишу у них нашел. Beta roadmap. Судя по ней всё готово к бете, осталось только документацию и экзамплы написать.

NikitaRzm commented 5 years ago

Тогда можно подождать, пока они закончат - и садиться изучать и пробовать применить на демке если все ок

antonk52 commented 5 years ago

@in19farkt про написание стилей все верно, можно писать стиле как эксклюзивно в отдельных css файлах как в стандартном подходе с css-modules, так и в js файлах как те же styled-components. Если подключен reshadow webpack loader то стили будут доставаться из js файлов во время сборки и не будут раздувать js бандлы и инлайниться в хэд при инициализации приложения.

Подход с написанием стилей в js файлов удобен только в двух случаях

PS: спасибо за багу в сафари на стойте документации, в ближайшее время пофксим =)