Прежде чем перейти к статье, хочу вам представить, экономическую онлайн игру Brave Knights, в которой вы можете играть и зарабатывать. Регистируйтесь, играйте и зарабатывайте!
Верней оформил 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 в веб-версии и нативной версии.