Pull to refresh

Mr. Stylin

Reading time4 min
Views8.9K

Вам не кажется, что мы слишком далеко зашли? Да вы, ну те что пишете на реакте. Вначале нам пришла гениальная мысль миксить представление с основным кодом, затем стали писать 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 {applyStyle} from './style.scss'

// sexy-button is css-class
const StyledButton = applyStyle(`sexy-button`, Button)

<StyledButton type='dashed'>
  Love me
</StyledButton>

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

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

Tags:
Hubs:
Total votes 23: ↑14 and ↓9+11
Comments24

Articles