Mr. Stylin

    Вам не кажется, что мы слишком далеко зашли? Да вы, ну те что пишете на реакте. Вначале нам пришла гениальная мысль миксить представление с основным кодом, затем стали писать CSS стили прямо в JS, как в том фильме “а тут всё в бак можно заливать с бензином”. Как сейчас помню вопли и негодование одних и счастье других, признаться честно, позже я и сам не брезгал styled-components-ами. Но на этом вся затея не остановились, нашлись и такие, что решили: “нафиг писать стили отдельно” и стали сразу передавать их в пропсы компонента. Такой подход хорошо отражается в styled-system и жутко напоминает те дикие времена когда балом правили эти господа: 

    <font color="red" face="Verdana" size="+1">
      Вы думали <b>я</b> <i>не вернусь</i>?
    </font>

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

    И вот что вышло:

    import {render} from 'react-dom'
    import {Title} from './styles.scss'
    
    render(
      <Title color='tomato' size='small'>
        Hello world!
      </Title>,
      document.getElementById('app')
    )

    styles.scss

    /**
      @tag: h1
      @component: Title
      size: small | medium | large
      color: #38383d --color
    */
    .title {
      --color: #38383d;
      color: var(--color);
      font-size: 18px;
    
      &.small {
        font-size: 14px;
        margin: 2px 0;
      }
      &.medium {
        font-size: 18px;
        margin: 4px 0;
      }
      &.large {
        font-size: 20px;
        margin: 6px 0;
      }
    }

    Если вы не заметили, тут есть два абсурда:

    import {Title} from './styles.scss'

    Тут мы импортируем реакт компонент сразу из scss стилей! Клянусь богом с таким успехом, в будущем мы будем импортировать компоненты из рисованных моков фигмы.

    Но, а далее следующий фокус в самих стилях. Обратите внимание на секцию комментарий и вы увидите аннотации которые напоминают собой JSDocs, хотя скорее их правильней назвать CSSDocs. Мы как бы говорим, что это за кусок стилей и намекаем для чего он нам нужен.

    Возможно эта анимация поможет вам разобраться более наглядно, что к чему:

    Если именовать CSS классы также как и значение свойств компонента то их можно сократить до type: primary | secondary | link, как было сделано в первом примере, полный список сокращалок можно найти по ссылке.

    Конечно, чтобы эта магия заработало, нужен специальный webpack loader и библиотека:

    npm install @stylin/style
    npm install --save-dev @stylin/msa-loader

    И внести некоторые изменения в конфигу вашего webpack-а.

    Однако, это еще не всё! Если вы из тех извращенцев, что используют TypeScript, то вы сможете получить авто-генерацию типов бонусом ко своим стилизованным компонентам. И знаете это так избавляет от скучной работы:

    Для этого вам надо установить еще один webpack loader и добавить его в конфигу.

    npm install --save-dev @stylin/ts-loader

    Полагаю, у вас возник вопрос типа: “Че там брат, че там под капотом?

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

    Но я, всё равно сравнил.

    Stylin быстрее порядком на 30% в сравнении с styled-components, а в определенных кейсах он делает styled-components как стоячего в несколько раз!

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

    Пример использования переменных:

    componentPropertyName: default-value --css-variable

    /**
      @tag: button
      @component: SexyButton
      width: 150px --btn-width
    */
    .sexy-button {
      --btn-width: 150px;
      width: var(--btn-width);
    }
    
    /* JSX */
    <SexyButton width='180px'>
      Love me
    </SexyButton>

    Темы

    Благодаря CSS переменным поддержка тем становится гораздо проще, вы полностью избавитесь от какой либо логики в стилях, всё будет в старой и доброй декларативной манере. Проверить это можно в онлайн демке, правда нужно отметить магия авто-генерации типов там не работает (в codesandbox нет доступа к FS), чтобы их пощупать вам придется стянуть исходники к себе и уже на локальной машине экспериментировать.

    Ах да, чуть ли не забыл, переключая темную тему на светлую и наоборот, вы заметите, что всё приложение не перерисовывается (react render) и это какая то магия!

    Естественно есть возможность пере-стилизовать существующие компоненты.

    import {Button} from 'antd'
    import {appleStyle} from './style.scss'
    
    // sexy-button is css-class
    const StyledButton = appleStyle(`sexy-button`, Button)
    
    <StyledButton type='dashed'>
      Love me
    </StyledButton>

    Я бы с удовольствием вам рассказал о всех возможностей данной библиотеки, однако я не хочу показаться, будто я пришел сюда пиариться :D. Я тут только, чтобы избавить вас от боли и послушать вашу критику / предложения. Может вы изволите такую балалайку и для вашего любимого фреймворка типа next.js или preact?

    Всем пока, будьте осторожны с реактом и берегите себя!

    Средняя зарплата в IT

    120 000 ₽/мес.
    Средняя зарплата по всем IT-специализациям на основании 6 277 анкет, за 1-ое пол. 2021 года Узнать свою зарплату
    Реклама
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее

    Комментарии 24

      0
      Порекламирую свой велосипед для React — css-vars-hook. Позволяет управлять CSS переменными из компонента.
      .box {
        background: var(--boxColor);
        width: var(--boxSize);
      }
      


      import {useTheme} from 'css-vars-hook';
      import 'style.css';
      
      export const DemoColor = () => {
        const theme = {
          boxColor: 'yellow',
          boxSize: '120px',
        };
      
        const [boxColor, setBoxColor] = useState(theme.boxColor);
      
        const {setRef, setVariable} = useTheme(theme);
      
        return (
          <div ref={setRef}>
            <fieldset>
              <label htmlFor="boxColor">
                Set box color. Needs to be a valid CSS color (name, HEX, rgba etc).
              </label>
              <input
                value={boxColor}
                id="boxColor"
                type="text"
                onChange={e => {
                  setBoxColor(e.target.value);
                }}
              />
              <button
                onClick={() => {
                  setVariable('boxColor', boxColor);
                }}
                type="button">
                Set
              </button>
              <div className="box" />
            </fieldset>
          </div>
      
      
        –9

        Тошнит от этой игры слов. Гламуризировали диктатора, у которого на руках кровь огромного количества людей, и радуются своему остроумию. И тут не подходит «хабр вне политики». Подобная бестактная глухота этот тоже политический или скорее нравственный выбор. Кто-то должен об этом говорить.

          –1
          ну раз тошнит, будем убирать этот балаган.
            –1

            Именно вы сейчас тяните разговор в сторону политики.


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

              0

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

                –3
                Сталин, Гитлер и прочие исторические диктаторы — это персонажи из разряда «или в истории — или никак». Пытаться выехать на популярных нынче патриотических нарративах — стыд и позор для автора.
              +3
              товарищ на картинке на Сталина или рядом вообще не похож, а вот на Гитлера да. Но сочтем это за пробелы автора в познании истории, а код пишется без таких казусов.
                –2
                Согласен, ну там он типа гламурный из другой вселенной.
                +2

                Всё пытаюсь понять чем же запись p fontSize=15 более ужасна и менее понятна, чем Title size="small"

                  +1

                  Например:
                  а) если позволить записывать fontSize=15, это значит, что можно записать и fontSize=16 и fontSize=17.51123, и fontSize=4. Это прямая возможность бардака, обычно же размеры разумно ограничены ui-китом.
                  б) fontSize=15 значит что размер будет 15 на всех размерах экрана. Экранов же много, и размер может требоваться разный на разных. Это позволяют делать медиазапросы: при size="small" размер может быть, например, 12 на телефоне, 16 на планшете и 20 на десктопе.

                    0

                    По поводу мобилок хороший аргумент, по поводу кита не совсем согласен. На проекте может быть штук 7 разных шрифтов, это значит неизбежно появление small, superSmall, extraSmall и тд.

                      +2

                      Да, вполне может, как и много других плохих вещей в работе) Но даже в таком негативном сценарии, я бы предпочёл 7 определенных размеров, вместо их неопределенного числа.

                    –1
                    Проблема начинается когда мы начинаем полностью стилизовать компонент через пропсы перенося CSS в JS код и в итоге от такого подхода получаются огромные элементы с возможными инлайн if-ами. Подход который я придерживаюсь прячет реализацию стилей под капотом, получаем только api (пропсы) которые можно дергать и менять состояние элемента.

                    Если речь идет о конкретном значении 15px vs small то ответ выше точно передает смысл этой затеи.
                    +1

                    Уж сколько лет прошло, но некоторые все еще продолжают служить богу separation of concerns, только вот зачем?


                    Не понравилось писать стили в JS-коде, это понятно. Но предлагаемая замена тоже сомнительная – теперь программируем в комментариях CSSDoc, чем это лучше?

                      –2

                      Что то мне этот JSX напоминает XML. А для преобразования XML в XHTML есть XSLT который уже встроен в браузер.

                        +2

                        Между JSX и XSLT общего примерно столько же, сколько у Java и Javascript, поэтому сравнения не получится

                          +2
                          JSX это просто сахар для createElement(type, props, children)
                          –11
                          Зачем вы пмхаете свой сраный js в топик java?
                            +1
                            Не покидает ощущение, что автор забыл добавить тэг «юмор» :)
                              +1

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


                              Вопрос: Что там на счёт сорцмапов? Я смогу безболезнено дебажить этот код?

                                +1
                                Всё по фэншую, сорцмапы включены.
                                Спасибо за фидбэк :)
                                +1

                                Как пользователю ts+react+styled-component решение мне нравится! Конечно, для использования в рабочих проектах, хочется сначала увидеть хотя бы небольшую, но сформировавшуюся, стайку пользователей. А вот для ближайшего pet-project попробую. Успехов!

                                  +2
                                  статьи с юморком мне нравятся, подняли настроение
                                    +1
                                    мы будем импортировать компоненты из рисованных моков фигмы

                                    /me задумался…

                                    Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

                                    Самое читаемое