Верней оформил 5 декабря 2023 года для всех то, чем его разработчики пользуются уже давно. Позиционируется данный помощник для js-подобных фреймворков типа React, Preact, Solid, lit-html и Angular, однако оперирующие html шаблонами Vue и Svelte тоже могут задействовать StyleX, но после предварительной специальной её кастомизации.
Код в React в итоге выглядит примерно так:
import * as stylex from '@stylexjs/stylex'; const colorStyles = stylex.create({ red: { backgroundColor: 'lightred', borderColor: 'darkred', }, green: { backgroundColor: 'lightgreen', borderColor: 'darkgreen', }, });
import * as React from 'react'; import * as stylex from '@stylexjs/stylex'; const styles = stylex.create({ ... }); function ReactDiv({ color, isActive, style }) { return <div {...stylex.props( styles.main, // apply styles conditionally isActive && styles.active, // choose a style variant based on a prop colorStyles[color], // styles passed as props style, )} />; }
StyleX компилируется в атомарные CSS, для чего используется Babel плагин.
Основная утверждаемая выгода от использования StyleX - переиспользование, типизация, будет всё круто на больших проектах. Ну и получение наконец полного "Single File Component" файла с js, css и html в одном флаконе.
Предполагается, что StyleX теперь будет продвигаться как best practice для React проектов.
Для сравнения DX вот примерно один и тот же код, написанный на React+StyleX и на Vue+CSS
Сравнить
React
import * as React from "react"; import * as stylex from "@stylexjs/stylex"; const colorStyles = stylex.create({ red: { backgroundColor: "lightred", borderColor: "darkred", }, green: { backgroundColor: "lightgreen", borderColor: "darkgreen", }, }); const styles = stylex.create({ main: { padding: "1rem", border: "1px solid grey", }, }); function ReactDiv({ color, isActive, style }) { return ( <div {...stylex.props( styles.main, isActive && styles.active, colorStyles[color], style, )} /> ); }
Vue
<script setup> import { ref } from "vue"; const color = ref("red"); const props = defineProps(["style", "isActive"]); </script> <template> <div class="main" :class="[color, { isActive: props.isActive }, props.style]" /> </template> <style scoped> .red { background-color: "lightred"; border-color: "darkred"; } .green { background-color: "lightgreen"; border-color: "darkgreen"; } .main { padding: 1rem; border: 1px solid grey; } </style>
Ну и интересны причины возникновения StyleX:
Предыдущий сайт Facebook использовал нечто похожее на CSS-модули и страдал от различных проблем, которые и вдохновили на создание CSS-in-JS. Средний посетитель facebook.com загружал десятки мегабайт CSS. Большая часть из них не использовалась. Чтобы оптимизировать первоначальную загрузку, мы лениво загружали наш CSS, что, в свою очередь, ��риводило к медленному обновлению (или "Interaction to Next Paint"). Использование сложных селекторов приводило к конфликтам или "войнам за специфичность". Инженеры часто прибегали к использованию !important или более сложных селекторов для решения своих проблем, что делало всю систему постепенно хуже.
Несколько лет назад, когда мы перестраивали facebook.com с нуля, используя React, мы поняли, что нам нужно что-то лучшее, и создали StyleX.
StyleX был разработан для масштабирования, и его дизайн доказал свою эффективность за годы использования. Мы добавили в StyleX новые функции без снижения производительности и масштабируемости, сделав StyleX еще более приятным в использовании.
Использование StyleX стало для нас в Meta значительным улучшением как в плане масштабируемости, так и в плане выразительности. На сайте facebook.com мы смогли сократить количество CSS-пакетов с десятков мегабайт лениво загружаемого CSS до одного пакета размером в пару сотен килобайт.
Мы создали StyleX не только для того, чтобы удовлетворить потребности React-разработчиков в стилях в Интернете, но и для унификации стилей для React в веб-версии и нативной версии.
