Material-ui: [RFC] Переход на стилизованные компоненты

Созданный на 11 февр. 2017  ·  164Комментарии  ·  Источник: mui-org/material-ui

Можем ли мы переключиться на стилизованные компоненты ?


Устаревшее сравнение

Он имеет много преимуществ перед JSS.
Вот сравнительная таблица, и в следующей версии даже не будет повторного рендеринга стилей SSR!

Особенности | стилизованные компоненты | реакция-jss
------------ | ------------- | -------------
Нет требований к сборке | ✅| ✅
Маленький и легкий | ✅ | ✅
Поддерживает глобальный CSS | ✅ | ✅
Поддерживает весь CSS | ✅ | ✅
Совместно | ✅ | ✅
Изолированный | ✅ | ✅
Не нарушает встроенные стили | ✅ |✅
Легко переопределить | ✅ | ✅
Тематика | ✅ | ✅
Рендеринг на стороне сервера | ✅ | ✅
Нет компонентов-оболочек | ❌ | ✅
поддержка ReactNative | ✅ | ❌

Условные обозначения: ✅ = Да, ❌ = Нет, 😕 = Типа, см. примечания или скобки

discussion enhancement

Самый полезный комментарий

@oliviertassinari В соответствии с нашим текущим тестированием производительности, как указано в https://github.com/mui-org/material-ui/issues/6115#issuecomment -643398897, я просто надеюсь, что команда по материалам не просто выбирает стилизованные компоненты, потому что они популярны. Это медленно. Всегда был. Лично для разработчика важно изучить такие вещи, как JS-нотация CSS.

Это часть работы.

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

Вот почему я использую только makeStyles и всегда использовал его с момента его появления.

Мой последний архитектор команд не стал слушать и начал работать со стилизованными компонентами, и теперь сайт работает медленно. Я переключился на makeStyles в тестовой ветке и сэкономил 50% (10 секунд) на TTI на мобильных устройствах, но, как вы сказали в этом комментарии, нотация JS известна не всем, поэтому она не была принята.

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

Все 164 Комментарий

@kybarg Спасибо, что открыли эту тему! CSS-in-JSS — это движущееся поле, выбор, который мы делали в прошлом, может перестать быть действительным по мере изменения проблем и решений.

Почему бы не использовать стилизованные компоненты в прошлом?

Прежде чем выбрать JSS, мы сравнили различные доступные решения по стилю.

Мы не выбрали styled-components по следующим причинам:

  • Стоимость абстракции. css-in-js-perf-tests — хороший ресурс, styled-components используют гламур внутри.

    • 126 КБ в разархивированном виде более 22 КБ для JSS

    • Время до первой покраски медленнее. Сравните время до первой отрисовки на эквивалентных демонстрациях https://github.com/MicheleBertoli/css-in-js , JSS работает на 40% лучше.

  • Предоставление className и возможности глубокого селектора CSS обеспечивают эффективную реализацию. Например, с <Grid /> : #6010.
  • Параллельный рендеринг на стороне сервера невозможен. Он полагается на синглтон для сбора стилей, в то время как JSS создает новый экземпляр для сбора стилей при каждом запросе. Отпаривание действительно ограничено.

На самом деле, стилизованные компоненты даже не существовали (существовали), когда @nathanmarks начал работать над отказом от встроенного стиля.

Сравнительная таблица

Поддерживает глобальный CSS

С https://github.com/cssinjs/jss-global вы можете писать такие вещи, как

const styles = {
  '<strong i="35">@global</strong> body': {
    color: 'green'
  }
}

Легко переопределить

Как это не легко? На стороне Material-UI у нас есть предопределенная таблица порядка инъекций. На территории пользователя они могут использовать афродизиак , который реализует отличный API переопределения афродиты.

Нет компонентов-оболочек

У нас нет компонента-оболочки на стороне Material-UI. Мы могли бы использовать withStyles , но не по соображениям производительности. Мы предоставляем этот компонент более высокого порядка пользователям, чтобы абстрагироваться от реализации контекста.

Тематика

Мы используем jss-theme-reactor внутри. JSS предоставляет низкоуровневый API, который делает это возможным.

Поддержка ReactNative

Это хороший момент, API-интерфейс react-with-styles довольно интересен. Это то, что мы могли бы улучшить!

Будущее

Забегая вперед, я думаю, что наиболее перспективным путем является наличие API, позволяющего переключать реализацию стиля. Это принесло бы нам две выгоды:

  • Material-UI меньше связан с каким-либо стилевым решением
  • Пользователи, использующие styled-components / aphrodite/... на своей стороне, могут сэкономить накладные расходы JSS, используемые внутри.

react-toolbox следует этому пути . Единственное, что меня беспокоит, это дополнительные накладные расходы. Я имею в виду, оно того стоит?

Я добавляю в цикл @kof и @mxstbr .

@kybarg На самом деле, я не уверен, что полностью понимаю, что вы предлагаете.
Мы не используем react-jss , как предполагает ваш вопрос.

Когда вы говорите «мы», вы имеете в виду пользователей или Material-UI?

Мои пункты:

  • styled-components — это библиотека гораздо более высокого уровня, чем ядро ​​JSS, вы наверняка можете использовать ее на уровне своего приложения.
  • Приведенная выше сравнительная таблица относится к react-jss, а не к ядру JSS, и является субъективным мнением Макса. Частично это неправда, а частично просто взгляд с какой-то конкретной точки зрения, которую мы не видим из таблицы.
  • Мы работаем над визуализацией динамических правил для более эффективного динамического стиля, jss-theme-reactor уже делает эту работу прямо сейчас, это просто вопрос оптимизации, которая, вероятно, не очень актуальна для MUI.
  • То, что MUI использует внутри, не должно волновать конечного пользователя. Все, что нужно сделать пользователю, должно быть возможным, даже не зная, что MUI использует внутри, или, по крайней мере, его более или менее обычный синтаксис cssinjs для тем.
  • Нам нужно получить варианты использования, которые MUI не поддерживает прямо сейчас, и решить их. Я всегда рад помочь процессу интеграции и доступен на Gitter.
  • Что такое реактивная нативная поддержка? Разве это не просто подмножество веб-платформы? Если это так, это должно просто работать, в противном случае дайте мне знать, что JSS должен уметь делать для поддержки React-Native, вот проблема .

Эта таблица действительно очень субъективна и основана на моем собственном опыте. FWIW, styled-components работает с любой сторонней библиотекой компонентов:

import { Button } from 'material-ui'

const MyButton = styled(Button)`
  // Only these styles will be overridden
  background: red;
`

Это работает до тех пор, пока компоненты прикрепляют свойство className внутренне к некоторому узлу DOM:

const MaterialUIButton = (props) => {
  /* ... */
  // As long as props.className is attached, the above usage will work
  return <button className={`bla ${props.className}`} />
}

Что такое реактивная нативная поддержка? Разве это не просто подмножество веб-платформы?

Нет, это не так просто 😉 Добавление поддержки JSS не должно быть сложным, так как все, что вам нужно сделать, это передать объект стиля в StyleSheet.create() . Это требует немного больше усилий со стороны styled-components , чтобы заставить строки CSS работать.


Я уже некоторое время разговариваю с @javivelasco , и мне нравится, куда он идет с react-toolbox . Его реализация потрясающая, и я бы хотел, чтобы все сторонние библиотеки компонентов приняли ее. Пингуем его, чтобы он мог поделиться своими идеями здесь!


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

Совершенно не связано, не могли бы вы прокомментировать в этом выпуске свои идеи для API, который позволил бы это сделать? Мы еще не решили, что будем делать, поэтому будем очень признательны за ваш вклад.

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

Я знаю, что material-ui _next_ вложил значительные средства в собственное решение jss.
Кто-нибудь обнаружил какое-либо серьезное преимущество использования jss над стилизованными компонентами?

Хотя jss хорош тем, что позволяет использовать несколько шаблонов, таких как декораторы (injectstyles) и плагины, я думаю, что простой подход со стилизованными компонентами намного чище, поскольку нет необходимости в декораторах, настраиваемых настройках и плагинах, потому что в этом нет необходимости.

В styled-comp каждый компонент уже имеет стиль, поэтому нет необходимости передавать стили. и вы передаете реквизиты, которые можно оценить для создания другого стиля
без настройки (createJss)
без плагинов (префикс)
нет JSON-DSL

Кто-то должен закрыть эту тему.

@rainice jss не имеет декораторов, HOC является деталью реализации react-jss и здесь не используется.

Почему это должно быть заблокировано? ИМХО нормальная дискуссия

Потому что контент для конечных пользователей здесь (а не для сопровождающих lib) очень поверхностен, и это понятно, потому что они не прочитали ни одной строки кода за тем, что они используют.

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

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

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

@mxstbr спасибо за стилизованные компоненты

Это работает до тех пор, пока компоненты прикрепляют свойство className внутренне к некоторому узлу DOM.

это, возможно, стоит выделить где-нибудь в вашем руководстве по использованию, когда mui: next будет выпущен. Этот комментарий меня просто спас.

Стили Flex для IE10 не работают с jss, но работают со стилизованными компонентами как шарм

@yhaiovyi Material-UI не поддерживает IE10.

Префикс поставщика evtl. Скоро будет исправлено для jss, но это не значит, что это решит все проблемы, если mui никогда не тестировался в IE10.

Во всяком случае, я пока не нашел никаких других проблем, кроме css flex с IE10.

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

Вы также можете получить API-интерфейс стилизованных компонентов, например, с помощью нескольких строк кода: https://material-ui-next.com/customization/css-in-js/#styled-components-api-15-lines-

Вы также можете использовать styled-jss , например: https://codesandbox.io/s/32mvjyjyxq .

Единственным недостатком JSS в целом является отсутствие автодополнения в редакторах кода, как сказано здесь , но преимущества есть, парсинг css в js, как в styled-components, немного перегружен.

редактировать: только что заметил указанную проблему чуть выше, интересно

Что раздражает, так это контекст Mui и withStyles HOC, похоже, не очень хорошо сочетаются с ядром react-jss и styled-jss ThemeProvider https://codesandbox.io/s/32mvjyjyxq (я пытался поставить Typography , но это не работает, редактировать: nvm, все еще возиться с этим)

Интересно, не будет ли позже (думаю, после v1) упростить src/styles/withStyles и двойной слой MuiThemeProvider + JSSProvider и сделать что-то более простое, например, как у react-jss и styled-jss

Полностью за это!

13 марта 2018 г., 13:55, «Кирилл Обуртин» [email protected] написал:

Что раздражает, так это контекст Mui и withStyles HOC, похоже, не играют.
хорошо с ядром react-jss и styled-jss ThemeProvider
https://codesandbox.io/s/32mvjyjyxq

Интересно, не будет ли позже (наверное, после v1) упростить
src/styles/withStyles и двойной слой MuiThemeProvider + JSSProvider


Вы получаете это, потому что подписаны на эту тему.
Ответьте на это письмо напрямую, просмотрите его на GitHub
https://github.com/mui-org/material-ui/issues/6115#issuecomment-372655385 ,
или заглушить тему
https://github.com/notifications/unsubscribe-auth/AADOWAbwLOnRoypx9ANCZnKyalZyD0M9ks5td8HNgaJpZM4L-GwD
.

разбор css в js, как в styled-components, немного перегружен

Точно так же, как синтаксический анализ объектов в CSS :wink: Парсинг строк примерно с той же скоростью, это, честно говоря, не имеет значения. https://github.com/A-gambit/CSS-IN-JS-Benchmarks/blob/master/RESULT.md

Решение | Используйте CSS | Использовать встроенные стили | Время монтирования (мс) | Время рендеринга (мс)
:--- | :--- | :--- | :--- | :---
...
стилизованные компоненты | + | - | 182 | 146,84
стилизованные компоненты-разделить-ячейку | + | - | 213,53 | 152,39
...
реагировать-jss | + | - | 198,97 | 297,74

@mxstbr полный парсер css, написанный на js во время выполнения, определенно имеет цену. Этот эталон не измеряет его стоимость.

полный парсер css, написанный на js во время выполнения, определенно имеет цену.

Конечно, но не больше, чем полноценный синтаксический анализатор CSS, который обрабатывает объекты, а не строки. Кроме того, синтаксические анализаторы CSS, работающие с реальными строками CSS, были оптимизированы и исследованы в течение длительного времени, а тем более парсеры, обрабатывающие объекты. :краснеть:

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

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

Да, это был бы подходящий тест, я немного протестировал, работа с объектами намного быстрее, например, в 10-20 раз быстрее.

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

Также тбх. не имеет значения, перейдем ли мы все в ISTF.

Я немного протестировал, работа с объектами намного быстрее, примерно в 10-20 раз быстрее.

Конечно, но 10 мс (именно столько времени требуется Stylis для анализа всей таблицы стилей начальной загрузки) против 1 мс для анализа всего CSS приложения не будут иметь значения в общей схеме, понимаете? Это не сделает и не сломает чье-либо приложение.

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

Кстати. этот тест кажется более точным: http://necolas.github.io/react-native-web/benchmarks/ Я не уверен, хотя он не полагается на кеш после первого анализа.

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

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

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

Я думаю, что проблема с блокировкой как инструмент, чтобы четко сообщить об этом, это нормально, это никого не оскорбило, и свобода слова не была нарушена. В данном случае это действительно хорошо.

Я снова открываюсь, чтобы собрать больше отзывов, мне любопытно, интересует ли это людей по-прежнему:

Capture d’écran 2019-03-10 à 10 38 56

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

  1. Размер пачки . Мы хотим, чтобы люди могли использовать один компонент, не платя за него 20 КБ в сжатом виде. По рейтингу:

    1. эмоция — лучший кандидат в этом направлении: 10kB gzip . Тем не менее, он используется немногими людьми. Если вы посмотрите на статистику загрузок, 80% исходят от сборника рассказов ?

    2. стилизованные компоненты весят около 16 КБ в сжатом виде . Его преимущество заключается в количестве людей, которые его используют. Может быть, 20% пользователей React?

    3. JSS с реактивной оберткой весом около 15 КБ в сжатом виде. Если вы посмотрите на статистику загрузок, большая часть использования связана с Material-UI.

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

    1. эмоция

    2. jss

    3. стилизованные компоненты

  3. API настройки . Настройка варианта должна быть легкой, настройка вложенного элемента должна быть легкой, добавление нового варианта должно быть простым. Прямо сейчас у нас есть API classes , API theme.overrides и возможность иметь глобальные детерминированные имена классов.
  4. Интероперабельность . Использование !important не является решением.
  5. RTL-поддержка

Я упомянул только стилизованные компоненты, эмоции и JSS, но это разные альтернативы: linaria, SASS и т.д.

Я считаю, что, возможно, стоит добавить следующие две проблемы, поскольку они могут помочь повлиять на решение, когда у вас будет время поработать над библиотекой CSS-in-JS, используемой Material-UI:

@o-alexandrov JSS следует той же стратегии, что и стилизованные компоненты? Я не понимаю вашей точки зрения. Не могли бы вы уточнить? Какая разница? Как лучше или стоит?

@oliviertassinari
В предыдущем сообщении я ничего не говорил о styled-components , за исключением того, что приветствую идею оценить использование styled-components или любой другой библиотеки CSS-in-JS, которая имела бы идеальный баланс:

  • опыт разработки (знакомство и гибкость, дальнейший вклад, фактическое использование разработчиками и т. д.)
  • представление

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

Лично мне нравится:

  • styled-components над jss для гораздо более широкого принятия сообществом.
    Я считаю, что принятие сообществом — это ключевой аспект, который должен учитывать пользовательский интерфейс материалов.

@o-alexandrov Хорошо, в таком случае я отмечаю ваш первый комментарий как не по теме. В v5 мы хотим изолировать основные компоненты от решения по стилю. Я бы хотел, чтобы мы могли предоставить голые, JSS, эмоциональные, linaria и styled-components (по умолчанию) версии компонентов. Это видение. Теперь реализация будет сложной!

Размер пакета

Доказано, что styled-components улучшает 12.3kB в @5.0.0-beta.8.

API настройки

Если они представят https://github.com/styled-components/styled-components/pull/2625 либо в пакете, либо во внешнем пакете, я считаю, что паритет API с Mui, поскольку в нем отсутствует API нестилизованных компонентов, который когда-нибудь нам может понадобиться , особенно в устаревших системах, но я не думаю, что вам понадобится этот API в самом Mui так часто.

Вне этого,

Я не уверен, какую информацию вы хотели бы собрать, так как из моего личного опыта styled-components предлагает функции, которые нам нужны.

Совместимость.

Что это для вас в данном контексте? Насколько я знаю, вы можете переопределить вещи в styled-components , как и в любой другой среде.

RTL-поддержка

Разве это не основано на том, как мы кодируем компоненты? Что именно styled-components или любая библиотека CSS-in-JS может предложить для этого?

Мои мысли

Скорость

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

Размер

v5 становится еще компактнее, как я сказал 12.3kB из 16.2kB , что представляет их усилия по этой теме.

Знакомство

Люди знакомы с API, так как он наиболее популярен. Фактически, большинство людей называют styled-components , ссылаясь на API, а не на фактический пакет, когда мы использовали API styled(...) ... , по большей части.

Реагировать на родной

Это имеет большое значение для Mui — это сеть, но люди будут продолжать принимать styled-components из-за этого.

Основная команда

Сильная основная команда, на сегодняшний день открыт 81 выпуск и 14 PR, это хорошие цифры для количества людей, использующих пакет.

Кроме того, такие люди, как @mxstbr , на самом деле используют пакет в spectrum , так что у него есть реальный опыт использования пакета, это потрясающе, это означает, что он действительно знает, каково это — использовать пакет.

Взял это

Что ж, лучше не бывает https://www.styled-components.com/docs/tooling

Для авторов пользовательского интерфейса

На сегодняшний день использование styled-components для компонентов Design System значительно возросло; Atlassian, GitHub, Orbit и многие другие.

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

TL;DR

Я поддерживаю styled-components .

Мне нравится JSS, потому что синтаксис объектов для CSS стал для меня проще, иногда я ленив и даже просто передаю эти стили как встроенный стиль style={{styles.dialogTitle}} , потом легко рефакторить

И его можно использовать по-разному, с оберткой элемента, такой как styled-components https://material-ui.com/styles/basics/#styled -components-api.

Мне очень нравятся стилизованные компоненты, но недавно я обнаружил, что они привносят ряд проблем, которые затрудняют последовательную работу встряхивания деревьев. Я знаю, что команда material-ui только что проделала большую работу, чтобы в этой библиотеке полностью работала древовидная тряска, и, очевидно, следует избегать любого регресса в этом вопросе.

К счастью, большинство его проблем с встряхиванием дерева решаются с помощью babel-plugin-styled-components и установки pure: true (см. https://www.styled-components.com/docs/tooling#dead-code-elimination). ). Но есть еще некоторые оставшиеся вопросы. Например:
https://github.com/styled-components/babel-plugin-styled-components/issues/245

Другой заключается в том, что использование внешней вспомогательной функции внутри ваших стилей может нарушить встряхивание дерева (если вы не настроите terser/uglify для игнорирования этой конкретной функции), например:

const Button = styled.button`
  font-size: ${externalHelperFunction()};
`

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

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

// components.js
import React from "react";
import styled from "styled-components/macro";

const Wrapper = styled.div`
  color: blue;
`;

export function MyComponent() {
  return <Wrapper>styled</Wrapper>;
}

MyComponent.displayName = "FancyName";

export function OtherComponent() {
  return "only";
}

// App.js
import React from 'react';
import { OtherComponent } from "./components";

/* code */

со значением по умолчанию create-react-app . MyComponent не будет включен в производственный пакет.

Это что-то, с чем только у rollup есть проблемы? Я был бы признателен за воспроизводимый пример, чтобы понять проблему.

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

const Wrapper = styled.div`
  color: blue;
`;

Wrapper.displayName = "FancyName";

export function MyComponent() {
  return <Wrapper>styled</Wrapper>;
}

export function OtherComponent() {
  return "only";
}

@mxstbr Да, хотя в обоих случаях стилизованные компоненты входят в комплект. Хотя установка displayName на MyComponent не включает MyComponent в пакет, он по-прежнему включает styled-components . Он в основном удаляет все, что было сделано для MyComponent , поэтому я изначально думал, что это правильно встряхивает деревья (просто искал FancyName .

Но он по-прежнему включает styled-components . Даже если вы считаете, что вызов styled имеет побочные эффекты, я бы рассмотрел

import React from "react";
import styled from "styled-components";

export function Wrapper() {
  // nonsense
  return styled.div``;
}

export function MyComponent() {
  return <Wrapper>styled</Wrapper>;
}

export function OtherComponent() {
  return "only";
}

как отсутствие побочного эффекта при импорте { OtherComponent } , но стилизованные компоненты все равно будут отображаться в комплекте (это даже без макроса). Так что либо это какая-то ошибка, либо я пропустил что-то большое. Четное

// Wrapper.js
import React from "react";
import styled from "styled-components";

export default function Wrapper() {
  // side-effect free module even if styled has side-effects
  const Component = styled.div``;
  return <Component />;
}

// components.js
// commenting this out removes styled-components from the bundle
export { default as Wrapper } from "./Wrapper";

export function OtherComponent() {
  return "only";
}

// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { OtherComponent } from "./components";
import * as serviceWorker from './serviceWorker';

ReactDOM.render(<OtherComponent />, document.getElementById('root'));

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();

будет включать styled-components (https://github.com/eps1lon/styled-components-shake).

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

Логично, спасибо за расследование.

Для этого варианта использования я не думаю, что имеет значение, включен ли styled-components в комплект (поскольку все компоненты должны его использовать), а скорее включены ли компоненты, которые вы не используете, что не имеет значения. звучит так, как будто это так, так что это хорошо, не так ли?

@mxstbr Это может быть серьезной проблемой, у нас есть пара не стилизованных и универсальных компонентов (Modal, Popper, TextareaAutosize, useMediaQueries и т. д.), скажем, кто-то использует

import { Modal } from '@material-ui/core';

с САСС. Мы ожидаем увеличения на +5 КБ в сжатом виде (на сегодняшний день), а не на +20 КБ в сжатом виде.

Однако, если предположить, что мы продвигаем @material-ui/unstyled вперед, на практике это может не иметь никакого значения, поскольку люди могут использовать этот пакет.

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

Я создал воспроизводимую демонстрацию здесь:
https://github.com/mbrowne/CRA-error-template/tree/styled-components-tree-shaking
git clone --single-branch --branch styled-components-tree-shaking [email protected]:mbrowne/CRA-error-template.git

Обратите внимание, что только Component1 корректно встряхивает дерево.

Хорошей новостью является то, что я думаю, что все эти проблемы решаемы, и @mxstbr , кажется, очень вовлечен в это. Скоро я буду работать над PR, который решит, по крайней мере, проблему статического реквизита (у меня уже есть работающий POC, использующий отдельный плагин Babel, который я написал).

Я открыл PR в компонентах в стиле babel-plugin, чтобы решить проблемы с встряхиванием дерева. Если кто-то здесь хочет помочь протестировать его, я думаю, @mxstbr приветствует это (и я, конечно, тоже):
https://github.com/styled-components/babel-plugin-styled-components/pull/248

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

Я думаю, если мы не хотим сделать это за один раз (я сомневаюсь, что мы этого хотим). Мы должны либо начать с того, чтобы заставить styled-components читать тему из jss, либо jss читать тему из стилизованных компонентов. Цель должна заключаться в том, чтобы мы могли переносить стили для каждого компонента.

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

Запрошено удаление комментария.

Эй, ребята, я тоже готов внести свой вклад ... отдельная ветка кажется нам разумной вещью ... давайте сделаем это ...!

@caprica-Six Спасибо за энергию, но новая ветка не нужна. Мы должны иметь возможность постепенно предоставлять версию стилизованных компонентов (+ jss и эмоции) (нестабильно в версии 4) и в то же время продвигать нестилизованную историю вперед. У меня есть POC, который мне нужно отправить. Styled-components (v5 beta) + dynamic props немного медленнее, чем то, что у нас есть с JSS и статическими стилями, но это все же должно быть приемлемо.

@oliviertassinari , мы можем с этим поучаствовать? Я как бы ждал, пока сопровождающий укажет мне правильное направление, прежде чем прыгать во что-либо

Почему вы не предпочитаете эмоции стилизованным компонентам? Кажется, причина в том, что «[эмоции] используются немногими людьми. Если вы посмотрите на статистику загрузок, 80% исходят из сборника рассказов?», Но это неправильно. Он используется чаще, чем styled-components ( сравнение ), и я не понимаю, почему 80% загрузок приходятся на сборник рассказов. Он явно растет намного быстрее, чем сборник рассказов.

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

Он легче, быстрее и имеет больше функций: переадресация свойств, готовый TypeScript (и отлично поддерживается по сравнению со стилизованными компонентами), готовый SSR Next.js (без необходимости перезаписывать файл _app. js и _document.js, на что у меня ушел один час в первый раз)

И более того, он больше используется, чем styled-components и явно имеет импульс.

@lcswillems Я думаю, что мы также должны поддерживать эмоции для людей, которые их предпочитают. Но я не думаю, что это должно быть по умолчанию.

  • «зажигалка»: неточно: https://bundlephobia.com/[email protected] (12,2 КБ) против https://bundlephobia.com/result?p=@emotion/ styled + https://bundlephobia.com/result?p=@emotion/core + https://bundlephobia.com/result?p=emotion-theming (13,1 КБ без учета общих зависимостей)
  • «Нестандартный SSR Next.js»: я думаю, что это серьезная проблема, встраивание

Спасибо за ваш ответ и исправление меня.

  • "зажигалка": вы правы
  • «Нестандартный SSR Next.js»: теперь я понимаю, почему они могут сделать SSR «из коробки» и почему их способ сделать это не самый лучший.
  • «больше используется, чем стилизованные компоненты»: я не уверен, что это надежно. Но мой источник тоже может быть ненадежным.
  • «быстрее»: я видел только устаревшие тесты, так что нет, у меня их нет.

Основная проблема, с которой я сталкиваюсь, — это перенаправление/фильтрация пропсов: https://github.com/styled-components/styled-components/issues/439 . Это случается со мной очень часто, и каждый раз делать фильтрацию вручную неудобно.

Но с вашими замечаниями эмоции кажутся менее хорошей альтернативой.

«зажигалка»: неточно: https://bundlephobia.com/[email protected] (12,2 КБ) против https://bundlephobia.com/result?p=@emotion/ styled + https://bundlephobia.com/result?p=@emotion/core + https://bundlephobia.com/result?p=emotion-theming (13,1 КБ без учета

В случае с Emotion, скорее всего, вы не будете использовать пакет @emotion/styled в пользу прагмы css props + @jsx . Также вам может не понадобиться пакет emotion-theming , пакет ThemeContext уже включен в пакет @emotion/core . Итак, это 12,2 КБ против 6,5 КБ.

встраивание

Просто любопытно: что эти обновления значат для пользователей библиотеки @material-ui/styles для компонентов, отличных от MUI? В моей компании мы используем его в качестве основы для большой внутренней библиотеки компонентов, сознательно выбрав его вместо styled-components , и мы очень довольны этим.

Просто решил проверить заранее, не запланировано ли какое-либо устаревание пакета @material-ui/styles , чтобы я мог планировать соответствующим образом.

В любом случае, спасибо за все замечательные вещи, которые вы все продолжаете предоставлять!

@nickjohnson-dev Переход на react-jss должен быть простым. Будет ли это работать для вашей организации?

@oliviertassinari Я думаю, что, скорее всего, так и будет. Пока мы можем сохранять общедоступный API самих компонентов в основном одинаковыми (локальные переопределения на основе classes , глобальные переопределения возможны в теме), я не думаю, что проблема изменить детали реализации.

Ожидаете ли вы, что появится какая-либо официальная документация по переходу с @material-ui/styles на другие параметры стиля после того, как MUI станет более независимым? На первый взгляд я не вижу каких-либо функций, отсутствующих в react-jss , которые мы используем в @material-ui/styles , но я не уверен, что я упустил что-то особенное, что делает пакет MUI. за кулисами.

@nickjohnson-dev Мы сделаем все возможное.

Если я правильно понимаю, то возникнет следующая проблема.
У нас есть многоразовый ComponentA . Мы делаем ComponentB , который использует ComponentA .

const ComponentA = ({className}) => (
  <div className={className}>
    <div className='inner' />
  </div>
);

const ComponentB = ({ className, classNameInner }) => (
  <div className={className}>
    <div className='inner'>
      <ComponentA className={classNameInner} />
    </div>
  </div>
)

const StyledComponentB = styled(ComponentB)`
     ???
`;

Обратите внимание, что и ComponentA , и ComponentB имеют элемент с одним и тем же className='inner' . Как мы будем нацеливать элемент $#$ .inner $#$ только на ComponentB ?

Привет, @oliviertassinari , спасибо, что поделились своими мыслями о стиле для следующей версии пользовательского интерфейса Material.

И спасибо также за Material UI. Сейчас я строю дизайн-систему поверх него.

Что касается принятия styled-components , кажется, что это принятое решение, и работа над достижением этой цели уже началась.

Тем не менее, я делюсь некоторыми наблюдениями, сделанными @croraf и @lcswillems.

Отличительной чертой текущего стиля пользовательского интерфейса Material является свойство classes .

Это простая идея, которая очень помогает с настройкой стиля и удобством сопровождения, потому что ввод classes является частью общедоступного интерфейса. Например, если мне нужно что-то настроить и я использую такой селектор, как & .Component-root , ничто не гарантирует, что Component будет поддерживать этот класс css в разных версиях. Имея хотя бы <Component classes={{root: ....}} /> , я могу получить ошибку проверки типа (при использовании TypeScript) об изменении интерфейса.

Как автор компонента, я могу решить документировать общедоступные (и поддерживаемые) классы и оставить другие недокументированными.

Я использовал style-components около 2 лет. Это правда, что он популярен, и он сильно эволюционировал. Но в примерах документации MUI я вижу ту же проблему, о которой упоминает @croad : использование селектора потомков & .inner очень хрупко, потому что вы можете распространять стили на подкомпоненты (и по своему собственному опыту я могу сказать это не угловой случай ... это случилось со мной несколько раз). Два возможных решения:

  • Используйте &.inner а затем везде используйте ${props.className}.inner . Я делал это много раз, и это больно писать.
  • Используйте > .inner , но тогда это зависит от структуры компонента. Добавьте несколько дополнительных div в середине, и он сломается.

Это правда, что JSS не популярен. Я узнаю об этом из-за MUI. Но после столь долгой работы с styled-components я обнаружил, что подход со стилями MUI освежает и с ним легче работать (через некоторое время наличие Styled HOC везде добавляет много дополнительной работы, и я начал ненавидеть эти стили). HOC... по крайней мере, это мой личный опыт). Эмоции более или менее соответствуют текущему подходу. И после прочтения ваших комментариев и некоторых проблем с производительностью JSS в некоторых случаях я рассматриваю возможность использования Emotion для системы дизайна.

Тем не менее, я вижу, что вы настолько убеждены в styled-components , что я хотел бы увидеть больше примеров того, как разрешить настройку стиля с помощью реквизитов classes . Те, что доступны в текущих документах MUI, разделяют проблемы, о которых я упоминал выше.

Есть ли другие способы использовать styled-components с поддержкой классов? Что вы думаете об этом?

JSS достаточно хорош и очень удобен в использовании. Есть ли веская причина для переезда?

Лично я думаю, что styled-component — это своего рода шаг назад, и JSS был главной причиной, по которой я начал использовать эту библиотеку, если честно.

@powerfulj Почему вы предпочитаете JSS стилизованным компонентам? Мне пришлось выбирать между этими двумя, и стилизованные компоненты показались мне лучше.

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

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

Отрицательная сторона заключается в том, что если у вас есть какой-то CSS (например, из инструментов разработки браузера), и вам нужно преобразовать его в JSS, вам придется потратить еще немного времени на настройку синтаксиса. С styled-component это происходит быстрее.

Просто чтобы поделиться своими выводами по этому вопросу.
Я попытался перенести некоторые демоверсии в стилизованные компоненты, как того требует #16947. Проблема с темой по умолчанию. makeStyles принимает параметры, в которых может быть передана defaultTheme. Существует оболочка makeStyles , которая предоставит defaultTheme . Затем хук useStyles проверит , предоставляет ли ThemeProvider тему, и если нет, внедрит defaultTheme .

Кажется, что в styled-components такой функциональности нет. В отсутствие ThemeProvider defaultTheme можно внедрить только методом .attrs . Мы можем создать что-то похожее на обертку makeStyles

import styledWithoutDefault from 'styled-components';
import defaultTheme from './defaultTheme';

const styled = Component => {
  return styledWithoutDefault(Component).attrs({ theme: defaultTheme });
};

export default styled;

Но метод .attrs просто перезапишет тему, предоставленную ThemeProvider , если таковая имеется. И я в настоящее время не знаю, как решить эту проблему.

Другая проблема заключается в том, что makeStyles использует пресет jss-plugin-default-unit , а стилизованные компоненты — нет. Таким образом, стилизованные компоненты не добавляют px к возвращаемому значению функции spacing() .
Возможное решение последней проблемы — использовать Styled-JSS, а не стилизованные компоненты.

Я рад здесь ваши идеи/предложения.

@fyodore82 .attrs работает как функция (см. https://www.styled-components.com/docs/api#attrs), так что подойдет:

```js
.attrs(({ тема = defaultTheme, ... реквизит }) => ({ ... реквизит, тема }))
````

@крораф

Мне это нравится, потому что я думаю, что он не вводит новый компонент, а вместо этого вы просто работаете со свойствами

Я думаю, что вы упустили очень хорошую вещь Styled-components: свойство css . Это позволяет вам добавлять CSS к компоненту без необходимости создавать новый.

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

Обратите внимание, что с помощью CSS prop компонент с CSS prop не имеет атрибута style , он уже преобразован в стилизованный компонент и поэтому имеет class . Если CSS становится больше и используется повторно, вы также можете создать новый компонент.

Отрицательная сторона заключается в том, что если у вас есть какой-то CSS (например, из инструментов разработки браузера), и вам нужно преобразовать его в JSS, вам придется потратить еще немного времени на настройку синтаксиса. С styled-component это происходит быстрее.

Я согласен. Это основная причина, по которой я им не пользовался. Большая часть CSS, написанного в Интернете, написана на CSS, а не на JSS. Поэтому, если вы хотите использовать какой-то код из StackOverflow, вам нужно сначала преобразовать его в JSS, что очень болезненно.

Другие дополнительные аргументы, которые заставили меня использовать Styled-компоненты:

  • На JSS писать больнее: приходится добавлять кавычки, подсветки синтаксиса нет (или я не нашел).
  • Новичкам понять сложнее. Все знают CSS, поэтому каждый может легко читать код со Styled-компонентами, чего нельзя сказать о JSS (синтаксис JSS обычно немного странный, особенно для псевдоселекторов и медиа-запросов).
  • Код становится менее читаемым. Чтобы проиллюстрировать этот момент, я переписал этот пример компонента Card с помощью Styled-components, чтобы показать, насколько яснее он может быть с ними.

JSS-версия:

import React from 'react';
import { makeStyles, useTheme } from '@material-ui/core/styles';
import Card from '@material-ui/core/Card';
import CardContent from '@material-ui/core/CardContent';
import CardMedia from '@material-ui/core/CardMedia';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import SkipPreviousIcon from '@material-ui/icons/SkipPrevious';
import PlayArrowIcon from '@material-ui/icons/PlayArrow';
import SkipNextIcon from '@material-ui/icons/SkipNext';

const useStyles = makeStyles(theme => ({
  card: {
    display: 'flex',
  },
  details: {
    display: 'flex',
    flexDirection: 'column',
  },
  content: {
    flex: '1 0 auto',
  },
  cover: {
    width: 151,
  },
  controls: {
    display: 'flex',
    alignItems: 'center',
    paddingLeft: theme.spacing(1),
    paddingBottom: theme.spacing(1),
  },
  playIcon: {
    height: 38,
    width: 38,
  },
}));

export default function MediaControlCard() {
  const classes = useStyles();
  const theme = useTheme();

  return (
    <Card className={classes.card}>
      <div className={classes.details}>
        <CardContent className={classes.content}>
          <Typography component="h5" variant="h5">
            Live From Space
          </Typography>
          <Typography variant="subtitle1" color="textSecondary">
            Mac Miller
          </Typography>
        </CardContent>
        <div className={classes.controls}>
          <IconButton aria-label="previous">
            {theme.direction === 'rtl' ? <SkipNextIcon /> : <SkipPreviousIcon />}
          </IconButton>
          <IconButton aria-label="play/pause">
            <PlayArrowIcon className={classes.playIcon} />
          </IconButton>
          <IconButton aria-label="next">
            {theme.direction === 'rtl' ? <SkipPreviousIcon /> : <SkipNextIcon />}
          </IconButton>
        </div>
      </div>
      <CardMedia
        className={classes.cover}
        image="/static/images/cards/live-from-space.jpg"
        title="Live from space album cover"
      />
    </Card>
  );
}

Версия со стилизованными компонентами:

import React from 'react';
import styled from 'styled-components';
import { useTheme } from '@material-ui/core';
import MuiCard from '@material-ui/core/Card';
import MuiCardContent from '@material-ui/core/CardContent';
import MuiCardMedia from '@material-ui/core/CardMedia';
import IconButton from '@material-ui/core/IconButton';
import Typography from '@material-ui/core/Typography';
import SkipPreviousIcon from '@material-ui/icons/SkipPrevious';
import MuiPlayArrowIcon from '@material-ui/icons/PlayArrow';
import SkipNextIcon from '@material-ui/icons/SkipNext';

export default function MediaControlCard() {
  const theme = useTheme();

  return (
    <Card>
      <Details>
        <CardContent>
          <Typography component="h5" variant="h5">
            Live From Space
          </Typography>
          <Typography variant="subtitle1" color="textSecondary">
            Mac Miller
          </Typography>
        </CardContent>
        <Controls>
          <IconButton aria-label="previous">
            {theme.direction === 'rtl' ? <SkipNextIcon /> : <SkipPreviousIcon />}
          </IconButton>
          <IconButton aria-label="play/pause">
            <PlayArrowIcon />
          </IconButton>
          <IconButton aria-label="next">
            {theme.direction === 'rtl' ? <SkipPreviousIcon /> : <SkipNextIcon />}
          </IconButton>
        </Controls>
      </Details>
      <CardMedia
        image="/static/images/cards/live-from-space.jpg"
        title="Live from space album cover"
      />
    </Card>
  );
}

const Card = styled(MuiCard)`
  display: flex;
`

const Details = styled.div`
  display: flex;
  flex-direction: column;
`

const CardContent = styled(MuiCardContent)`
  flex: 1 0 auto;
`

const CardMedia = styled(MuiCardMedia)`
  width: 151px;
`

const Controls = styled.div`
  display: flex;
  align-items: center;
  padding-left: ${props => props.theme.spacing(1)}px;
  padding-bottom: ${props => props.theme.spacing(1)}px;
`

const PlayArrowIcon = styled(MuiPlayArrowIcon)`
  height: 38px;
  width: 38px;
`

Наконец, я не смог найти никаких преимуществ использования JSS.

css очень хорош и в основном устраняет недостатки, о которых я упоминал. (подражатели формируют стилизованные компоненты :D)

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

@lcswillems

Не спорю ни за одно решение, ни за другое, просто отмечаю пару ваших моментов:

если вы хотите использовать какой-то код из StackOverflow, вам нужно сначала преобразовать его в JSS, что очень болезненно

Существует расширение VSCode для преобразования CSS в CSS-in-JS, хотя оно не всегда работает идеально. В любом случае, я бы не назвал это болезненным.

у вас нет подсветки синтаксиса

Я не совсем понимаю этот аргумент. Это просто объект JS, поэтому подсветка синтаксиса любого редактора работает:

image

(но, возможно, вы ищете что-то более конкретное?)

Что касается сравнения двух примеров, я не нахожу его более читабельным. Хотя отсутствие реквизитов className, возможно, является более чистым, из основного блока кода JSX не очевидно, относятся ли компоненты к собственным компонентам MUI или к измененным без необходимости перекрестных ссылок на компоненты styled() . В более крупном компоненте они могут быть удалены далеко.

Вызовы styled() (для меня) менее читаемы, чем объект JSS (хотя я представляю, что вы к ним привыкли).

@powerfulj Почему вы предпочитаете JSS стилизованным компонентам? Мне пришлось выбирать между этими двумя, и стилизованные компоненты показались мне лучше.

Потому что я сам являюсь разработчиком Typescript и предпочитаю создавать все в объекте Typescript. Особенно я ненавижу струны.

Хотя нам нужно перенести код CSS в код JSS из-за разницы, я все же предпочитаю читать код JSS, потому что структура выглядит как традиционный CSS (ориентированный на классы), я бы потратил больше времени на чтение кода стилизованного компонента, потому что он длиннее а можно и тут и там.

Я думаю, что люди заявили об этом изменении только потому, что у них есть опыт работы с Styled-компонентом в прошлом. Это дает мне ощущение, что «почему бы нам не выбрать библиотеку, с которой мы знакомы, но без очевидной выгоды?».

С моей точки зрения, JSS просто удобен, мы можем организовать объект, используя все способы Javascript, такие как

{
...общийJSS1,
...общийJSS2,
что бы ни
}

Кроме того, у нас есть плавные динамические темы, интегрированные с типами, и мы получили все подсказки типов как из типов className, так и из типов css.

Новым разработчикам, особенно разработчикам Typescript, просто понравится JSS.

К вашему сведению, можно сделать некоторую вложенность в styled-components, если вам не всегда нужен отдельный компонент для всего. Как правило, это не рекомендуется, поскольку использование отдельных компонентов со значимыми именами считается более чистым и читаемым в соответствии с философией стилизованных компонентов, но в документации говорится, что это нормально, если «использовать экономно». И, конечно же, для тех, кто не разделяет эту философию, они могут делать больше вложений. В качестве примера того, что я имею в виду под вложением:

const Wrapper = styled.div`
  display: block;

  .inner {
    flex: 1;
  }
`

...
  <Wrapper>
    <div class="inner">...</div>
  </Wrapper>

Подробнее см. https://www.styled-components.com/docs/faqs#can -i-nest-rules.

Дискуссии о предпочтениях стиля кодирования могут продолжаться вечно.

После некоторого использования styled-components мне больше нравится подход JSS, потому что:

  • Когда стили становятся длиннее, я обычно перемещаю их в отдельный файл.
    Я сделал это и с styled-components , и я считаю, что useStyles / makeStyles легче писать, читать и поддерживать. Например. import useStyles from './MyComp.styles' против import {XStyled, YStyled,...} from './MyComp.styles' ... поддержание этих вариаций ...Styled с их типизацией в TS раздражает.
  • Я склонен делать вещи прогрессивно: сначала я начинаю с черновика, используя div и классы, а затем рефакторинг их в компоненты. При использовании styled-components я делаю это с помощью внутренних классов (как в примере от @mbrowne), но это требует дополнительной работы по рефакторингу. Я нашел подход useStyles гораздо более удобным для работы с этим рабочим процессом.
  • Литералы шаблонов хороши для вставки кода CSS, но ужасны, когда вам приходится использовать переменные темы/реквизита. Проблема с вставкой кода легко решается с помощью плагина, но редактирование с помощью переменных и функций внутри литерала шаблона не так уж и сложно.

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

Мой самый большой открытый вопрос касается изменения использования classes .

В примерах использования className и внутренних классов есть проблемы (см. мой предыдущий комментарий). Опора css в styled-components не является вариантом решения этих проблем. В отличие от функции css в Emotion, реквизит css полагается на присоединение к компоненту (это означает, что вы не можете использовать его в стиле кода useStyle/makeStyles/classes ).

Прикрепление стилей к компоненту не является второстепенным дизайнерским решением. Для меня это и хорошие, и плохие стороны JSS. Стилизованные компоненты и Emotion полагаются на плагины Babel и взаимодействуют с React для обработки кэширования и генерации имен классов для SSR. Преимущество JSS в том, что ему не нужны никакие плагины Babel. Плохо то, что SSR в JSS требует больше работы, и я видел сообщения об ошибках в этой области.

Вернемся к MUI. У меня сложилось впечатление, что внедрение компонентов стиля означает использование className и внутренних классов в качестве единственного способа настройки стилей. Стилизация становится более согласованной для разных фреймворков: вы можете использовать проп styled или css , пока компонент использует className , вы в порядке.

Но для меня удаление реквизита classes — это шаг назад. Эта поддержка помогает документировать и набирать настройки стиля проверки. Возможно, можно найти золотую середину, например, использовать стилизованные компоненты, но сохранить поддержку classes (без необходимости взлома внутреннего класса). В API стилевых компонентов я не нашел ничего, что могло бы помочь в этом случае. Вот почему может быть полезно оценить технические проблемы JSS. Потому что, если главной проблемой является популярность, эмоция тоже становится популярной (см. переписать makeStyles .

@dfernandez-asapp, вы сделали несколько замечательных замечаний, просто ответив на небольшую часть этого fwiw @styled-components поддерживает использование объекта, похожего на jss, вместо строки https://www.styled-components.com/docs/advanced# стиль -объекты

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

К вашему сведению, можно сделать некоторую вложенность в styled-components, если вам не всегда нужен отдельный компонент для всего. Как правило, это не рекомендуется, поскольку использование отдельных компонентов со значимыми именами считается более чистым и читаемым в соответствии с философией стилизованных компонентов, но в документации говорится, что это нормально, если «использовать экономно». И, конечно же, для тех, кто не разделяет эту философию, они могут делать больше вложений. В качестве примера того, что я имею в виду под вложением:

const Wrapper = styled.div`
  display: block;

  .inner {
    flex: 1;
  }
`

...
  <Wrapper>
    <div class="inner">...</div>
  </Wrapper>

Подробнее см. https://www.styled-components.com/docs/faqs#can -i-nest-rules.

Любая поддержка типа для этого? Или мы должны поставить строку везде?

Я не понимаю, почему так много шумихи вокруг стилизованных компонентов. Это похоже на шаг назад, если честно. Типизированные свойства CSS JSS с TypeScript намного удобнее и проще в обслуживании, плюс есть проверка синтаксиса как часть JS — любой современный/настроенный редактор сообщит вам, если вы когда-нибудь сделаете опечатку, и даже поможет вам с автоматическим завершением, если это необходимо.

edit: он напечатан, см. ответ South-Paw ниже.

@martinjlowm выглядит так, как будто у него есть типизация?

image

См.: https://styled-components.com/docs/advanced#style -объекты.

Вы говорите, что не понимаете этой шумихи... но я тоже не понимаю всей ненависти, которую она вызывает. 🤷‍♂

Эмоции и стилизованные компоненты — это значительные улучшения по сравнению с объектами стилей CSS.

@martinjlowm выглядит так, как будто у него есть типизация?

...

См.: https://styled-components.com/docs/advanced#style -объекты.

Вы говорите, что не понимаете этой шумихи... но я тоже не понимаю всей ненависти, которую она вызывает. 🤷‍♂

Эмоции и стилизованные компоненты — это значительные улучшения по сравнению с объектами стилей CSS.

Я понимаю! Я не знал, что он поддерживает такие объекты. Мое беспокойство было связано с CSS в строках шаблона, но если объекты являются опцией, то я ничего против этого не имею!

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

Прямо сейчас кажется глупым удалять сгенерированные сервером таблицы стилей и заставлять клиент повторно отображать все стили :(

@martinjlowm выглядит так, как будто у него есть типизация?
...
См.: https://styled-components.com/docs/advanced#style -объекты.
Вы говорите, что не понимаете этой шумихи... но я тоже не понимаю всей ненависти, которую она вызывает. 🤷‍♂
Эмоции и стилизованные компоненты — это значительные улучшения по сравнению с объектами стилей CSS.

Я понимаю! Я не знал, что он поддерживает такие объекты. Мое беспокойство было связано с CSS в строках шаблона, но если объекты являются опцией, то я ничего против этого не имею!

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

Прямо сейчас кажется глупым удалять сгенерированные сервером таблицы стилей и заставлять клиент повторно отображать все стили :(

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

image

@Южная Лапа

Эмоции и стилизованные компоненты — это значительные улучшения по сравнению с объектами стилей CSS.

Я все еще не понимаю, почему любой разработчик React может заниматься этим. Если вы хотите поместить свой CSS в строки шаблона, почему бы вам просто не использовать Angular и не поместить свой HTML в строки шаблона? Сила React в том, что элементы JSX на самом деле являются просто объектами JS, которые у вас есть масса возможностей для изучения и преобразования, и то же самое касается JSS.

Движущей силой CSS в движении JS является тот факт, что JS значительно превосходит CSS для выполнения динамических задач, и немалую роль в этом играет мощь объектов JS.

Тот факт, что styled-components поддерживает объекты, является отвлекающим маневром:

  • Он поддерживает их, но по какой-то причине говорит: «Это особенно полезно, когда у вас есть существующие объекты стилей и вы хотите постепенно перейти к стилизованным компонентам». Очевидно, они не видят ценности в возможности манипулировать объектами, и похоже, что объекты стиля всегда будут рассматриваться как граждане второго сорта в их API.
  • Документы не дают понять, поддерживает ли он селекторы CSS реального мира, подобные этому, с JSS:
{
  color: 'black',
  '&$error': {
    color: 'red'
  }
}

Даже Emotion отдает должное ценности объектам стиля и относится к ним как к первоклассным гражданам:

Написание стилей с помощью объектов — мощный паттерн, встроенный непосредственно в сердцевину эмоций.

@lcswillems , вы недооцениваете, насколько сложно постоянно создавать все эти маленькие HOC (и тот факт, что большинство систем автоимпорта недостаточно умны, чтобы знать, хотите ли вы импортировать @material-ui/core/Card как Card или MuiCard (и если вы все еще пишете операторы импорта вручную, вы сильно тратите свое время))

const Card = styled(MuiCard)`
  display: flex;
`

const Details = styled.div`
  display: flex;
  flex-direction: column;
`

const CardContent = styled(MuiCardContent)`
  flex: 1 0 auto;
`

const CardMedia = styled(MuiCardMedia)`
  width: 151px;
`

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

Именно об этом говорит @dfernandez-asapp, когда говорит:

(через некоторое время наличие Styled HOC везде добавляет много дополнительной работы, и я начал ненавидеть эти HOC... по крайней мере, это мой личный опыт)

HOC в значительной степени должны умереть. Это устаревший шаблон. Например, react-redux вышел с хуком useSelector , который в 100 раз удобнее, чем HOC connect , Apollo перешел с HOC на хуки, то же самое и с хуком useStyles Хук withStyles .

Трудности с преобразованием скопированного CSS в JSS — гораздо более решаемая проблема, если есть интерес, я даже сделаю расширение VSCode для его автоматизации или веб-сайта.

если есть интерес, я даже сделаю расширение VSCode для его автоматизации

@ jedwards1211 Есть paulmolluzzo.convert-css-in-js , но если вы сможете улучшить его для JSS, я уверен, что это будет приветствоваться.

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

@ jedwards1211 Я прочитал то, что вы сказали, и на мгновение отступил от всего этого - это просто напоминает мне комментарии людей, которые спорят об использовании табуляции вместо пробелов. Реальность такова, что на самом деле не имеет значения, что вы используете, если в итоге получается полезный продукт.

Оставляйте свои мнения/горячие точки зрения в Twitter или Reddit, и мы можем обсудить их там – но давайте не будем и дальше раздувать эту проблему бессмысленными пламенными войнами о строках шаблонов и объектах для CSS… Я думаю, мы все можем согласиться, что мы лучше чем это 😄

Спасибо, что указали, что не стоит менять статус-кво в MUI? 😉

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

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

@ jedwards1211 jedwards1211 , даже если вы вынуждены использовать стилизованные компоненты, существует альтернативный синтаксис css prop , представленный в v4 , который вы можете использовать - по крайней мере, таким образом вам не нужно беспокоиться о присвоение префиксов стилизованным компонентам (MuiCard, StyledCard и т. д.).

import { Avatar } from '@material-ui/core';

// CSS is separate from the markup 👍
const avatarStyle = css`
  width: 32px;
  height: 32px;
  border-radius: 50%
`;

// No wrappers, prefixes in the markup (such as <MuiAvatar>, <StyledAvatar> etc.) 👍
function SomeComponent(props) {
  return <div> ... <Avatar css={avatarStyle} /> ... </div>
}

@ jedwards1211 ваш пример также можно упростить до следующего, если вы использовали стилизованные компоненты

const Card = styled(MuiCard)`
  display: flex;

  ${MuiCardContent} {
    flex: 1 0 auto;
  }

  ${MuiCardMedia} {
    width: 151px;
  }
`

const Details = styled.div`
  display: flex;
  flex-direction: column;
`

@koistya , поддержка css довольно крутая, хотя важное предостережение заключается в том, что она реализована с помощью плагина Babel, поэтому она не для всех, особенно для людей, которые используют tsc для компиляции своих файлов tsx. Также я предполагаю, что это приведет к тому, что TypeScript или, по крайней мере, Flow будут жаловаться на то, что компонент не имеет реквизита css .

Я думаю, что в основном просто недоволен потенциальным нарушением, которое это может вызвать в моем приложении. @oliviertassinari упомянул на днях, что он думает о том, чтобы сделать styled-components по умолчанию в MUI v5. И, надеюсь, это будет необязательным, и JSS все еще можно будет использовать, но мы посмотрим, смогут ли они это реализовать, знаете ли. Это стало шоком — действительно ли был проведен тщательный референдум о предпочтениях всей пользовательской базы? Я бы ожидал Emotion, потому что сейчас он намного популярнее.

Также я предполагаю, что это приведет к тому, что TypeScript или, по крайней мере, Flow будут жаловаться на то, что компонент не имеет поддержки css.

Можно настроить.

Но действительно ли был проведен тщательный референдум о предпочтениях всей пользовательской базы?

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

Я бы ожидал Emotion, потому что сейчас он намного популярнее.

Как вы измеряли популярность?

⚠️ Эмоции значительно реже выбираются разработчиками, чем styled-компоненты (/6, насколько я помню). Если вы считаете загрузки на npm, удалите сборник рассказов и выберите количество загрузок (оно огромно).

@eps1lon вот что я искал: https://2019.stateofcss.com/technologies/css-in-js/

Однако я ошибался, к сожалению, все, что я помнил, это кажущийся восходящий тренд, хотя это не график популярности с течением времени (очень сомнительный дизайн графика):
image

Может быть настроен

Есть ли способ заставить TypeScript предположить, что все элементы JSX поддерживают реквизит css ? Я не знаю, как настроить Flow для этого.

РЕДАКТИРОВАТЬ : к счастью, я нашел способ для TypeScript, но не уверен, что есть способ для Flow.

Эта проблема является самой популярной из всех, что у нас когда-либо были.

Понимаю. Вздох

FWIW, один из главных участников styled-components , похоже, недружелюбно относится к системам типов:

https://github.com/styled-components/styled-components/issues/3012#issuecomment -583878486

Я был бы гораздо более уверен в идее перехода на стилизованные компоненты, если бы они заботились об опыте разработки пользователей TS/Flow...

@ jedwards1211 есть макрос Babel для css , если это поможет. Особенно исходя из css/scss/less, я не думаю, что всем нравится переходить на «стилизованный» способ.

Хотя какие цели? Как насчет производительности? Например, некоторые системы поддерживают атомарный css. Исходя из Tailwinds, он делает вещи намного чище и, возможно, быстрее.

@hc-codersatlas вы можете найти некоторые тесты в packages/material-ui-benchmark .

@koistya , если я правильно прочитал, эмоции выглядят намного быстрее, чем остальные.

@oliviertassinari действительно ли большинство разработчиков «делают» этот выбор? Согласно вашему упоминанию о реакции-выборе и сборнике рассказов, большинство разработчиков, вероятно, будут использовать все, что входит в комплект с компонентами пользовательского интерфейса, а материальный-пользовательский интерфейс является большой единицей. Если то, что входит в комплект, не является ужасным, никто не собирается увеличивать размер своего пакета и тратить больше усилий с другой системой поверх того, что уже использует инфраструктура пользовательского интерфейса.

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

например, втулка использует стилизованные компоненты, которые многие компании используют/использовали в 1 точке.

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

Если будут изменения, пожалуйста, измените на лучший 1, основываясь на технических достоинствах, а не на популярности. Я предсказываю, что если material-ui использует какую-либо библиотеку, она станет популярной 1, поскольку mui сам по себе является 1 из самых популярных фреймворков пользовательского интерфейса.

image

@ South-Paw предложенное вами упрощение не сработает, вы не можете использовать ${MuiCardContent} в своем примере, потому что MuiCardContent не является стилизованным компонентом.

https://styled-components.com/docs/advanced#referring-to-other-components

По сути, невозможно избежать всех отдельных оболочек HoC. Хотя, подумав об этом некоторое время, я понял, что это в основном такое же количество решений по вводу/именованию, что и с JSS.

@mbrookes @oliviertassinari как будут обрабатываться условные стили и стили внутренних компонентов?
Например, каким будет styled-components -эквивалент следующего?

// conditional class name
<MenuItem classes={{selected: classes.selectedItem}}>...</MenuItem>

// inner component class name
<Dialog classes={{paper: classes.dialogPaper}}>...</Dialog>

Я успокоился по поводу идеи перехода на styled-components , но я хочу убедиться, что есть надежный план для обработки таких случаев использования, потому что я предполагаю, что API должен быть очень другим или полагаться на имена классов стиля БЭМ.

@ jedwards1211 ах, моя ошибка. У меня сложилось впечатление, что пример был, если бы они были стилизованными компонентами, но на самом деле это не сработает, если это не так 👍

@ jedwards1211 clsx - это то, что я видел в прошлом в паре со стилизованными компонентами для условных классов - это то, что вы имеете в виду?

Проекты, которые я делаю в данный момент, используют стилизованные компоненты, обертывающие компоненты MUI по мере необходимости, поэтому я не использовал ни один из условных стилей MUI.

@ South-Paw это (или classnames ) может быть внутренней деталью решения, но я имею в виду, что, поскольку обертки styled-components вводят только один className AFAICT, не будет на самом деле это не удобный способ передать несколько имен классов переопределения в компонент. Вместо этого нам, возможно, придется сделать что-то вроде <Dialog Paper={StyledPaper}>...</Dialog> , и я даже не уверен, что для выбранного примера класса MenuItem .

@ jedwards1211 jedwards1211 , не могли бы вы сделать быстрый пример, чтобы я мог лучше понять, какой вариант использования вы описываете, и в чем, по вашему мнению, проблема? Я хотел бы попробовать помочь с решением, но я просто пока не понимаю, к чему это относится 😄

Да, у меня нет времени сегодня вечером, но завтра я буду.
Также у меня есть работа над jss-codemorphs , и в конечном итоге я планирую сделать расширение VSCode для преобразования вставленного CSS в JSS.

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

Интересно отметить, что я читал, что Facebook может также открыть решение CSS-in-JS. Было бы полезно взглянуть на это, когда оно выйдет.

Касательно актуальной темы. Мне не нравятся стилизованные компоненты из-за того, что опыт работы с Typescript невелик. Типы часто больше вредят, чем помогают. Медленная компиляция, безумные интерфейсы (попытка понять, как стилизованные компоненты работают через интерфейс, превращается в кошмар из-за всей этой вложенной магии Pick ). Пока у styled-components есть этот тип DX, для material-ui это будет шагом назад.

Интересно отметить, что я читал, что Facebook может также открыть решение CSS-in-JS.

@venikx Насколько вероятно, что это произойдет? В последний раз, когда я слышал о чем-то, что могло бы предположить, что это было в https://reactpodcast.simplecast.fm/75 , казалось, что это цель на 5 лет.

Ого, правда? Я не знал, что они уже дали "график времени". По какой-то причине я предположил, что это произойдет примерно в то же время, что и Concurrent Mode. Очень жаль.

При этом моя точка зрения о стилизованных компонентах остается в силе. Я предпочитаю использовать чистый способ обработки стилей material-ui вместо использования стилизованных компонентов. Кажется, что типизация из styled-components предназначена для компилятора, а не для документации.

Еще одна раздражающая вещь (но это, вероятно, снова личные предпочтения) — это то, как вы справляетесь с динамическим применением стилей к компоненту. Я очень предпочитаю добавлять или удалять имена классов, а не встраивать эту логику в стилизованный компонент.

На данный момент API Material-UI действительно чистый, имхо.

Мне не нравятся стилизованные компоненты из-за того, что опыт работы с Typescript невелик.

Я использовал styled-components и Typescript вместе по крайней мере в 4 крупных проектах до сих пор, и у меня не было никаких проблем с типами — они могут быть немного неуклюжими при работе в библиотеке компонентов, но это было бы в конце MUI. - не на стороне потребителей.

Медленное время компиляции

Я не сталкивался с этим ни в одном проекте, над которым я работал, который их использует - у вас есть пример того, что вы имеете в виду?

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

Вы также можете подумать о том, чтобы внести свой вклад в проект @types , если считаете, что можете как-то улучшить их — я уверен, что каждый будет признателен за любую работу, если это улучшение по сравнению с тем, что есть сейчас!

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

Ничто не мешает вам использовать классы со стилизованными компонентами:

const Box = styled.div`
  height: 160px
  width: 160px;
  background-color: black;

  .red {
    background-color: red;
  }
`;

// simple usage
<Box className="red" />

// get more complex with conditionals and using something like clsx (https://www.npmjs.com/package/clsx)
const isRed = true;
<Box className={clsx({ red: isRed })} />

Стоит отметить, что, несмотря на некоторые комментарии, утверждающие обратное, в родительском выпуске 150 👍 и 27 🎉 и только 18 👎 и 9 😕. Похоже, есть активное меньшинство, которому не нравится это обсуждение, и большинство, считающее это позитивным шагом 🤷‍♂

@ South-Paw Проблема с голосованием в том, что единственный выбор: JSS против стилизованных компонентов. Вокальная часть заключается в том, что им не нравятся стилизованные компоненты, а не в том, что им нравится JSS. Может быть, если голосование

В конце концов, все лучше, чем JSS. Это старое. Он медленный и громоздкий (размер пакета), и его следует продвигать. Таким образом, голоса никак не подтверждают ваш вывод.

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

Я слежу за дискуссиями по этой теме от основной команды.

Я думаю, что вы недооцениваете мнение основной команды, и лично я считаю, что вам следует прекратить спорить на эту тему и больше доверять основной команде; в конце концов, основная команда должна решить, в каком направлении будет работать Material UI.

Если вы действительно твердо придерживаетесь мнения об этом, Material UI обладает удивительной лицензией MIT, разветвите его и продолжайте придерживаться того видения, которое у вас есть, я призываю вас сделать это, возможно, в будущем мы научимся из разнообразной среды.

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

Вот что красивого посмотреть

image

В конце концов, все лучше, чем JSS. Это старое.

@hc-codersatlas старый == зрелый - не могли бы вы пояснить, почему это проблема?

Хорошо, кажется горячей проблемой, но может ли кто-нибудь подтвердить эту простую информацию: в настоящее время возможно использовать синтаксис, подобный styled-components , с теговыми литералами шаблонов, которые выглядят как CSS, в текущих версиях Mui (4 или 5) ?
Я не мог найти четкого ответа да или нет на этот вопрос. Меня не волнует базовая технология, только удобство для разработчиков. Копирование и вставка CSS из InVision в некоторых случаях весьма полезно.

Эта проблема касается решения для стиля, используемого в Material-UI, ваш вопрос, похоже, касается того, как вы стилизуете свое приложение / изменяете стиль компонентов, для которых вы можете использовать любое решение:

https://material-ui.com/guides/interoperability/

JSS имеет базовую поддержку литералов шаблонов в качестве подключаемого модуля.

Я только что закончил реализацию очень всеобъемлющего конвертера CSS в JSS:

Надеюсь, это избавит вас от необходимости копировать и вставлять CSS в стили JSS.

@jedwards1211 посмотри это
https://css2js.dotenv.dev/

@nainardev Я заметил, что и другие утилиты очень ограничены, они конвертируют атрибуты CSS, но не конвертируют селекторы, вложенные селекторы, ключевые кадры анимации, медиа-запросы и т. д. Из-за этого я сделал свой инструмент очень полным, он может конвертировать надеюсь, любой полноценный CSS, который вы ему бросите.

Возможно, где-то пропустил этот ответ, но все равно хочу его поднять. Мы находимся в процессе перехода на компоненты материального пользовательского интерфейса, а также оцениваем наше решение по стилю ( less против makeStyles против styled-components ), большая часть нашего стиля выполняется с помощью less файлы, и большая часть нового кода MUI использует makeStyles , что я хочу уточнить, так как это будет частью v5, что мы можем сделать, чтобы уменьшить технический долг, связанный со стилем?

  1. Будет ли makeStyles в v5? Как это будет работать с styled-components и темами? Например, как это будет выглядеть с styled-components :
const useStyles = makeStyles((theme) => ({
  paper: {
    padding: theme.spacing(2),
    textAlign: 'center',
    color: theme.palette.text.secondary,
  },
}));
  1. (v4) Есть ли лучший способ получить объект theme в стилизованной строке шаблона, чем этот, чтобы я мог использовать его несколько раз?
const StyledContainer = styled.div`
  color: ${({ theme }) => theme.palette.primary.main};
  padding: ${({ theme }) => theme.spacing(1)};
  background-color: ${({ theme }) => theme.palette.background.paper};
`;
  1. Предполагая, что makeStyles присутствует в v5, должны ли мы ожидать какого-либо снижения производительности, если мы используем как поставщика тем styled-components , так и поставщика тем Material UI для большой кодовой базы?

Мне нравится использовать Material UI, спасибо за всю тяжелую работу!

@эгилсстер

  1. Да, либо из @material-ui/styles, либо из react-jss, увидишь.
  2. Да https://material-ui.com/guides/interoperability/#theme ,
const StyledContainer = styled.div`
  ${({ theme }) => `
  color: ${theme.palette.primary.main};
  padding: ${theme.spacing(1)};
  background-color: ${theme.palette.background.paper};
  `}
`;
  1. Основные проблемы: 1. накладные расходы на настройку, единовременные затраты, 2. загрузка двух сред выполнения CSS-in-JS, которые имеют накладные расходы ~ 15 КБ в сжатом виде, стоимость аналогична, скажем, включая Sentry: https://bundlephobia.com /result?p=@sentry/browser.

Спасибо за быстрый ответ, очень признателен.

  1. Да material-ui.com/guides/interoperability/#theme

Это довольно круто. Вероятно, за этим последует некоторая работа с инструментами, проект, который я переношу, не использует TS, но VSCode / языковой сервер, похоже, не имеет ни малейшего представления о том, что такое theme в этом случае, и я теряю styled-components подсветка синтаксиса тоже.

Еще раз спасибо, буду продолжать следить за этим развитием.

@oliviertassinari , если произойдет переход на стилизованные компоненты, будет ли это означать, что мы больше не можем полагаться на CSS API, такие как <ListItem classes={{ selected: myCustomClassName}}> ?

@ jedwards1211 API classes останется.

Хорошо. Я немного смущен тем, как MUI будет использовать стилизованные компоненты внутри, поскольку стилизованные компоненты могут применять только один класс к корневому элементу.

const MyRoot = styled('div')`
  // some nice styles
`;

const MyAwesomeChild = styled('div')`
  // some nice styles
`;

export function AwesomeRoot(props) {
  return (
    <MyRoot className={props.classes?.root}>
      <MyAwesomeChild className={props.classes?.child}/>
      {props.children}
    </MyRoot>
  );
}

Имеет ли это смысл @jedwards1211 ?

@yordis Я знаю, это кажется таким простым, но как бы вы реорганизовали составные селекторы, такие как https://github.com/mui-org/material-ui/blob/master/packages/material-ui/src/Button/Button.js #L75 ?

Я действительно не могу придумать способ сохранить это существующее поведение с помощью styled-components , поэтому это может привести к большему количеству критических изменений, чем ожидают люди.

  outlined: {
    '&$disabled': {
      border: `1px solid ${theme.palette.action.disabledBackground}`,
    },
  },

Существующий код и пользовательские переопределения, вероятно, в некоторых случаях также зависят от специфики CSS.

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

const MyOutlinedComponent = styled('div')`
  ${props.disabled && `
      border: `1px solid ${({ theme }) => theme.palette.action.disabledBackground}`,
  `}
`;

<MyOutlinedComponent disabled/>

@yordis возможно. Как я уже сказал, хотя люди, вероятно, не думают о том, сколько критических изменений это вызовет для пользователей, я не думаю, что этот пример предотвратит критические изменения.

Не могли бы вы поделиться реальными примерами и реальными потенциальными критическими изменениями?

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

@oliviertassinari будут ли переопределения темы работать без изменений в v5? Чтобы следующий пример переопределения работал, кажется, что MUI по-прежнему должен применять имена классов, сгенерированные JSS, в дополнение к имени корневого класса, сгенерированному styled-components .

const theme = createMuiTheme({
  overrides: {
    MuiButton: {
      root: {
        '&$disabled': {
          color: myCustomColor,
        },
      },
    },
  },
});

@yordis , подумав об этом подробнее, я понял, что составные селекторы для стилей, переданных через реквизит classes , к счастью, все равно будут работать. Однако не уверен насчет стилей переопределения темы.

Я имел удовольствие использовать оба стилизованных компонента поверх MUI, а также простой стилизованный MUI с использованием style={object}.

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

Использование стилизованных компонентов увеличило время рендеринга почти на полсекунды; по сравнению с const useStyles = makeStyles или style={object}.

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

@Icehunter , не могли бы вы опубликовать свои результаты и образец проекта в Интернете, чтобы люди могли его посмотреть?

@Icehunter , не могли бы вы опубликовать свои результаты и образец проекта в Интернете, чтобы люди могли его посмотреть?

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

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

@Icehunter , вы отправляете какие-либо реквизиты этим стилям? будь то 50 карт или 500 карт, количество сгенерированных классов должно быть одинаковым. похоже, что ваш конкретный пример содержит проприетарный код, которым нельзя поделиться, но сможете ли вы воспроизвести эту проблему с кодом, которым вы можете поделиться?

API-интерфейсы styled() / styled.div добавляют дополнительную нагрузку на отрисовку _каждого_ элемента, поэтому даже при кэшировании имен классов это может быть медленнее. С помощью makeStyles вы можете прикрепить группу стилей один раз, а затем просто применить имена классов вручную, что зачастую значительно быстрее.

Я собрал пример CodeSandbox , чтобы проиллюстрировать, что решения, основанные на стилизованных компонентах styled , могут быть в 3-4 раза медленнее, чем MUI makeStyles :
image

API-интерфейсы styled хороши для удобства, но я повторяю мнение @Icehunter о том, что это может быть проблемой производительности при интенсивном использовании в списках/таблицах. Приятно иметь makeStyles в качестве резервной копии.

@schnerd Спасибо, что собрали эти примеры, они очень хорошо иллюстрируют проблему. Так же, как примечание, предварение поста фразой «Это нетрудно увидеть ...» может показаться снисходительным и на самом деле не добавляет к отличному набору примеров.

@tuxracer приносит свои извинения — обновлено.

@Icehunter Я не понимаю, что вы имеете в виду, вы использовали общие стили с SC или JSS?

@Icehunter Я не понимаю, что вы имеете в виду, вы использовали общие стили с SC или JSS?

Оба на самом деле. В итоге мы остановились на makeStyles, но либо это, либо использование styled={object} дали нам те же результаты производительности.

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

С точки зрения стека это написано в nextjs.

Просто чтобы быть ясным (редактировать):

Я использовал SC по назначению, оборачивая компоненты mui. Получилось очень медленно.

Затем я использовал компоненты mui, используя makeStyles и/или style={object} из общей настройки файла, и локальные (имитация каскадирования). Гораздо быстрее.

Я вовсе не хочу блокировать эту идею; но если это по умолчанию; тогда должен быть способ переопределить глобально сверху вниз выбор по умолчанию и dep ввести свой собственный.

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

const MyOutlinedComponent = styled('div')`
  ${props.disabled && `
      border: `1px solid ${({ theme }) => theme.palette.action.disabledBackground}`,
  `}
`;

<MyOutlinedComponent disabled/>

Может быть, я опоздал на эту игру. Но я думаю, что @jedwards1211 ищет способ выразить это с помощью SC: https://codesandbox.io/s/magical-snow-5bzd8

У меня самого такое есть в некоторых местах. Так что было бы неплохо, если бы было просто перейти на v5, когда этот день наступит.

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

Например, если пользовательский интерфейс Material будет поддерживать переопределение вариантов Typography по умолчанию в будущем, я думаю, что JSS проще, чем стилизованные компоненты.

@heb-mm здесь есть подробный RFC, в котором @oliviertassinari упомянул эту ветку 7 марта.

Мне потребовалось менее минуты, чтобы прокрутить вверх и увидеть упоминание.

Редактировать: для тех, кому интересно, heb-mm удалил свой комментарий.

Я собрал пример CodeSandbox , чтобы проиллюстрировать, что решения, основанные на стилизованных компонентах styled , могут быть в 3-4 раза медленнее, чем MUI makeStyles :

@schnerd Я обновил ваш тест, включив в него собственный API-интерфейс Material-UI styled , который должен имитировать styled-components . Я был удивлен, увидев, насколько он невероятно медленный по сравнению с другими вариантами. См. https://codesandbox.io/s/css-in-js-comparison-ljtjz?file=/src/App.js .

image

Кто-нибудь знает, будет ли @emotion/styled (который имеет в основном тот же API, что и стилизованные компоненты) столь же медленным? Мне просто интересно, есть ли что-то в их реализации, что можно было бы лучше оптимизировать.

Кто-нибудь знает, будет ли @emotion/styled (который имеет в основном тот же API, что и стилизованные компоненты) столь же медленным? Мне просто интересно, есть ли что-то в их реализации, что можно было бы лучше оптимизировать.

https://codesandbox.io/s/css-in-js-comparison-sej1m

image

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

Хм, это может немного помешать нашим планам перехода на MUI. В настоящее время мы отказываемся от styled-components в пользу системы стилей пользовательского интерфейса Material после того, как столкнулись с множеством проблем с управлением CSS, темами и производительностью. styled components поначалу было все в порядке, мы создали на его основе собственное тематическое решение, но когда пользовательский интерфейс вырос, вырос и CSS. Мы используем TypeScript, поэтому тот факт, что мы могли легко рефакторить объект JS вместо встроенной строки CSS, был огромным преимуществом. 😕

Итак, я новичок в Material UI, а также только что увидел альфа-версию v5. @ldiego08 ты сказал:

В настоящее время мы отказываемся от styled-components в пользу системы стилей Material UI.

Я обычно использую стилизованные компоненты при работе с React. Что такое система стилей Material UI и как рекомендуется использовать стили и CSS в Material UI в будущем? Я прочитал эту страницу, и мне не ясно, поддерживаете ли вы CSS-IN-JS или нет: https://material-ui.com/system/basics/. Я обычно предпочитаю писать CSS не в объектном синтаксисе, и я наслаждался преимуществами использования CSS-IN-JS, поскольку вы можете использовать «обычный синтаксис CSS», но также иметь под рукой мощь JS.

Спасибо за любую помощь в работе!

Я не знаю, почему API стилевых компонентов так популярен. Это медленнее, вам нужно обернуть все в компонент, а не просто генерировать имя класса. И еще, что не так с теговыми литералами шаблонов? Мы не хотели писать css в css-файлах, потому что гораздо лучше писать его в виде строки javascript? :D Синтаксис объекта намного мощнее, когда дело доходит до композиции, рефакторинга и т. д. Для меня простые функции эмоций css и cx, которые принимают объект css и возвращают имя класса, являются наиболее гибким и мощным API. Таким образом, просто генерировать имена классов с эмоциями и использовать API классов — это супергибко и мощно. Поэтому я не понимаю, почему вы обмениваете производительность и гибкость на «более удобный API для разработчиков» (для некоторых людей, для меня, это ужасный API).

Я не знаю, почему API стилевых компонентов так популярен. Это медленнее, вам нужно обернуть все в компонент, а не просто генерировать имя класса. И еще, что не так с теговыми литералами шаблонов? Мы не хотели писать css в css-файлах, потому что гораздо лучше писать его в виде строки javascript? :D Синтаксис объекта намного мощнее, когда дело доходит до композиции, рефакторинга и т. д. Для меня простые функции эмоций css и cx, которые принимают объект css и возвращают имя класса, являются наиболее гибким и мощным API. Таким образом, просто генерировать имена классов с эмоциями и использовать API классов — это супергибко и мощно. Поэтому я не понимаю, почему вы обмениваете производительность и гибкость на «более удобный API для разработчиков» (для некоторых людей, для меня, это ужасный API).

У меня была такая же проблема :) возможно, это немного проясняет ситуацию:
https://github.com/mui-org/material-ui/issues/6115#issuecomment-580449539

@martinjlowm Да, мы на одной волне :) Я думаю, что самый разумный способ для команды материального пользовательского интерфейса — реализовать какое-то подключаемое решение, а не использовать какое-либо решение css в js, позволяя людям выбирать, что использовать и таким образом сохраните размер пакета. А также сохранение классов и API createMuiTheme, потому что это самая мощная его часть. Для меня css в js — это простой динамический стиль на основе состояния компонента, уверенность при рефакторинге или удалении css или целых компонентов (вот где объектный подход лучше), производительность (не загрузка кучи неиспользуемых стилей из кучи внешних таблиц стилей) , и т.д.. И опять же, я не понимаю, почему людям нравится писать строку с подсветкой какого-то редактора. Я имею в виду, что вы должны использовать ${} для доступа к свойствам из контекста. Для чего-то более сложного, чем установка элемента background od div, этот подход, на мой взгляд, беспорядочный и нечитаемый. Я не осуждаю, просто говорю то, что думаю, и пытаюсь доказать, что не всем разработчикам нравятся стилизованные компоненты, а даже если и нравятся, я не вижу смысла жертвовать производительностью и гибкостью ради этого. :)

@vdjurdjevic Действительно, соединение material-ui с одним решением css в js является почти гарантированным рецептом конфликта, когда практики css-in-js неизбежно развиваются в разных направлениях.

Как насчет некоторого шаблона адаптера, который применяет стили с помощью определенного поставщика css-in-js? Сами стили должны быть определены в согласованном формате в пакетах material-ui. Именно применение этих стилей осуществляется соответствующими адаптерами по-разному.

Что-то вроде:

import {EmotionAdapter, StyledComponentAdapter, ThemeProvider} from "@material-ui/core/styles";
...
return 
    (<ThemeProvider theme={theme} adapter={EmotionAdapter}>
        ...
    </ThemeProvider>)

@vdjurdjevic Я в значительной степени согласен с вашими мыслями на https://github.com/mui-org/material-ui/issues/6115#issuecomment -652762320. Вам может понравиться это краткое изложение направления, в котором мы движемся, которым я недавно поделился в https://github.com/mui-org/material-ui/issues/16947#issuecomment -653797178.

Я не понимаю, почему людям нравится писать строку с подсветкой какого-то редактора.

Пара причин с моей точки зрения:

  • Близко к тому, почему мы не пишем React.createElement('div', {}) .
  • Люди с ограниченным опытом в веб-разработке (а их много) изо всех сил пытаются изучить JavaScript API, с синтаксисом CSS это кажется проще. Возьмем, к примеру, дизайнеров, спросите у членов вашей команды, что они об этом думают :).
  • Невозможно скопировать и вставить между инструментами разработчика и исходным кодом (я ненавижу это).

@oliviertassinari Хорошо, это важные моменты, я согласен :) Но все же для меня (не дизайнера, не новичка, старшего разработчика) стилизованные компоненты и литералы шаблонов с тегами никогда не были бы вариантом. Я прочитал ваше резюме для дальнейшего развития, и я рад услышать, что движок css будет необязательным. Я не возражаю против стилизованных компонентов по умолчанию (если это нравится большинству пользователей), если я могу это переключить. И, честно говоря, я думаю, что в своем следующем проекте я буду придерживаться JSS с v4, у него есть несколько приятных функций (например, расширения и компоновка плагинов). Мне пришлось написать плагин для стилиса для эмоций, чтобы было что-то похожее.

PS. Я тоже не большой поклонник JSX :) Он быстро становится беспорядочным, вы получаете код со стрелками, а для компонентов, которые должны отображать динамические элементы, у вас нет другого выбора, кроме как использовать createElement. Не говорю, что работать напрямую с createElement лучше, просто говорю, что JSX не идеален. На мой взгляд, у Flutter лучший DX, я надеюсь, что когда-нибудь он сможет хорошо справляться с веб-платформой.

@oliviertassinari В соответствии с нашим текущим тестированием производительности, как указано в https://github.com/mui-org/material-ui/issues/6115#issuecomment -643398897, я просто надеюсь, что команда по материалам не просто выбирает стилизованные компоненты, потому что они популярны. Это медленно. Всегда был. Лично для разработчика важно изучить такие вещи, как JS-нотация CSS.

Это часть работы.

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

Вот почему я использую только makeStyles и всегда использовал его с момента его появления.

Мой последний архитектор команд не стал слушать и начал работать со стилизованными компонентами, и теперь сайт работает медленно. Я переключился на makeStyles в тестовой ветке и сэкономил 50% (10 секунд) на TTI на мобильных устройствах, но, как вы сказали в этом комментарии, нотация JS известна не всем, поэтому она не была принята.

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

[Вопрос перенесен в StackOverflow.]

@haysclark Пожалуйста, используйте StackOverflow для вопросов поддержки, а не добавляйте их в RFC.

@haysclark Пожалуйста, используйте StackOverflow для вопросов поддержки, а не добавляйте их в RFC.

@mbrookes Спасибо за предупреждение!

Кто-нибудь знает, будет ли @emotion/styled (который имеет в основном тот же API, что и стилизованные компоненты) столь же медленным? Мне просто интересно, есть ли что-то в их реализации, что можно было бы лучше оптимизировать.

https://codesandbox.io/s/css-in-js-comparison-sej1m

image

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

Мне было интересно, как производительность компонента Box будет сравниваться с вашим профилированием, и я добавил Box Chakra-UI для хорошей оценки, и результаты были ... удивительными: P
https://codesandbox.io/s/css-in-js-comparison-forked-mg3gx?file=/src/App.js

image

@Nvveen , вы пробовали Chakra-UI v1? Он был переписан и, надеюсь, должен быть лучше. Также есть эмоция v11, хотя она все еще находится в стадии бета-тестирования.

@Nvveen , вы пробовали Chakra-UI v1? Он был переписан и, надеюсь, должен быть лучше. Также есть эмоция v11, хотя она все еще находится в стадии бета-тестирования.

Только что попробовал с последним RC, но заметной разницы нет; он по-прежнему примерно в 1,5-2 раза медленнее обычного SC. Самый большой вопрос для меня, почему MUI Box такой медленный.

@Nvveen , вы пробовали Chakra-UI v1? Он был переписан и, надеюсь, должен быть лучше. Также есть эмоция v11, хотя она все еще находится в стадии бета-тестирования.

Только что попробовал с последним RC, но заметной разницы нет; он по-прежнему примерно в 1,5-2 раза медленнее обычного SC. Самый большой вопрос для меня, почему MUI Box такой медленный.

Он использует JSS. СК хоть немного лучше.

На моей машине порядок выполнения тестов влияет на результаты. Сравнивать

  1. Коробка сначала https://codesandbox.io/s/css-in-js-comparison-forked-tqlg1?file=/src/App.js
    Capture d’écran 2020-08-16 à 19 49 55

  2. Последний ящик https://codesandbox.io/s/css-in-js-comparison-forked-js6th?file=/src/App.js
    Capture d’écran 2020-08-16 à 19 49 45

Сборка мусора @oliviertassinari и jit из v8 - вот что вызывает это. Лучше, чтобы тестовые прогоны были изолированы/разделены на самом деле. В более поздних тестах jit лучше, но время от времени он запускает сборку мусора.

Похоже, что Emotion, SC и Chakra близки к теоретической максимальной производительности, когда каждый маленький компонент имеет свои собственные стили для монтирования, а стиль MUI еще не полностью оптимизирован. Похоже, что единственный способ улучшить производительность — это иметь одну таблицу стилей для всего дерева компонентов, как в makeStyles/pure CSS. Я предполагаю, что дополнительные 30 мс для эмоций, SC и т. д. — это неизбежные накладные расходы каждого маленького компонента, который должен убедиться, что его стили смонтированы.

@ jedwards1211 jedwards1211 , если речь идет о сохранении dx, Atlassian создала библиотеку, которая компилирует ее в css, называемую скомпилированной

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

revskill10 picture revskill10  ·  3Комментарии

finaiized picture finaiized  ·  3Комментарии

chris-hinds picture chris-hinds  ·  3Комментарии

reflog picture reflog  ·  3Комментарии

TimoRuetten picture TimoRuetten  ·  3Комментарии