Недавно компания Facebook* (aka Meta**) выпустила в опенсорс собственную CSS-in-JS библиотеку под названием StyleX. По заявлениям разработчиков, она отлично подходит для больших проектов и ключевым ее преимуществом является перфоманс.

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


Начать стоит с того, что StyleXframework agnostic. Это означает, что библиотеку можно использовать с любым JS фреймворком, будь то React, Preact, Solid, Angular или Qwik. Однако те, что используют кастомные расширения файлов, типа Svelte и Vue, могут потребовать дополнительной настройки.

Предлагаю взглянуть на компонент Button, написанный на React и TypeScript:

import * as React from "react";
import * as stylex from "@stylexjs/stylex";
import type { StyleXStyles } from "@stylexjs/stylex/lib/StyleXTypes";

const MEDIA_MOBILE = "@media (max-width: 700px)" as const;

const ButtonStyles = stylex.create({
  base: {
    border: "none",
    background: "none",
    cursor: "pointer",
    // Использование медиа-запросов
    fontSize: {
      default: "24px",
      [MEDIA_MOBILE]: "16px",
    },
  },
  primary: {
    color: "white",
    backgroundColor: "black",
  },
  secondary: {
    color: "black",
    backgroundColor: "white",
  },
  block: {
    display: "flex",
    width: "100%",
  },
  dynamic: (opacity) => ({
    opacity,
  }),
});

const Button = ({
  color = "primary",
  block = false,
  styles,
}: {
  color: string;
  block: boolean;
  styles?: StyleXStyles<{
    backgroundColor?: string;
    color?: string;
  }>;
}) => {
  return (
    <button
      {...stylex.props(
        // Применяется по умолчанию
        ButtonStyles.base,
        // Применяется один из вариантов в зависимости от пропса color
        ButtonStyles[color],
        // Применяется условно в зависимости от пропса block
        block && ButtonStyles.block,
        // Применяется результат выполнения функции dynamic
        ButtonStyles.dynamic(state.opacity),
        // Стили, прокинутые пропсом
        styles
      )}
    />
  );
};

Библиотека имеет довольно простое API, мы разберем основные функции и типы. С остальными можно ознакомиться по ссылке.

С помощью stylex.create() создается объект стилей, свойства которого мы можем передать в stylex.props() условно, по ключу или динамически – с использованием функции. Так как props() возвращает объект, его нужно развернуть через spread-оператор.

А используя встроенный тип StyleXStyles мы можем ограничить css-свойства, передаваемые извне.

В StyleX также доступно создание переменных, на которых можно строить дизайн-систему:

import * as stylex from '@stylexjs/stylex';

const colors = stylex.defineVars({
  accent: 'blue',
  background: 'white',
});

Обращение к ним происходит так же, как и к обычным свойствам объекта:

import * as stylex from '@stylexjs/stylex';
import {colors} from './vars.stylex.js';

const styles = stylex.create({
  container: {
    color: colors.accent,
    backgroundColor: colors.background,
  },
});

Ключевые преимущества

Разработчики библиотеки декларируют ряд достоинств:

  • Перфоманс – библиотека на этапе компиляции с помощью Babel-плагина превращает JS в оптимизированный по размеру единый CSS файл, таким образом мы избегаем классических CSS-in-JS проблем с рантаймом.

  • Масштабируемость – гениальный Babel-плагин использует кэширование на уровне файлов и генерирует атомарные названия классов, за счет чего минимизируется размер бандла, а рост количества компонентов в приложении не сильно отражается на размере CSS файла.

  • Предсказуемость – приоритизация селекторов в StyleX очень проста – всегда побеждает последний заданный стиль. Это значит, что можно забыть про каскадность.

  • Комбинируемость – объекты стилей можно экспортировать и передавать в компоненты. При этом стили всегда будут вести себя предсказуемо.

  • Типизация – каждое css-свойство и переменная полностью типизированы, а мы можем использовать TypeScript или Flow, чтобы определить стили, передаваемые в компонент.

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

История создания

Идея создать новую систему работы с CSS зародилась несколько лет назад, когда разработчики Meta начали переписывать фронтенд фейсбука на React.

Ранее в проекте использовалось нечто похожее на CSS-модули и lazy loading, но у этого подхода были проблемы с масштабированием. При навигации по сайту модули подгружались в разном порядке, что порождало различные казусы с приоритизацией стилей.

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

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

В результате перехода на StyleX размер первоначального CSS бандла facebook.com составил 140 Кбайт. На первый взгляд может показаться, что это много, но нужно учитывать, что эти стили покрывают 100% приложения. Браузер загружает их всего один раз, а потом достает кэша.

Конкуренты

По-моему, сравнивать StyleX, в первую очередь, стоит с Emotion и Tailwind.

Тут у нас, как и в Emotion, co-located подход – стили находятся в одном файле с компонентом. Для многих это большой плюс с точки зрения DX и читабельности кода. Но в то же время, StyleX обгоняет конкурента за счет отсутствия рантайм-нагрузки.

В сравнении с Tailwind, библиотека не так проста и удобна – мы не можем использовать сокращения из коробки, их придется создавать самостоятельно.

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

Заключение

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

Компания Facebook* три года тестировала и дорабатывала свой продукт, прежде чем отдать его в опенсорс. Мне кажется, это достаточное основание полагать, что библиотека проверена и может использоваться в реальных проектах.

Лично я рад появлению этой технологии, а что думаете вы?

*Социальная сеть запрещена в России

**Компания Meta Platforms Inc. признана в России экстремистской организацией и запрещена.

Комментарии (71)


  1. markelov69
    17.12.2023 14:52

    Лично я рад появлению этой технологии, а что думаете вы?

    В мусорку такое. Даже близко не лучше чем SCSS + CSS Modules.

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

    И чем же это лучше чем классика в виде SCSS + CSS Modules?


    1. Spaceoddity
      17.12.2023 14:52

      А чем ваша "классика" лучше ванильного CSS?))


      1. Akuma
        17.12.2023 14:52

        Вложенными селекторами.

        Ну кто-то ещё циклы фигачит, но это баловство.

        Остальное нафиг не нужно, ага. Но то что в статье - лютая дичь какая-то :)


        1. Spaceoddity
          17.12.2023 14:52

          Вложенными селекторами.

          https://developer.mozilla.org/ru/docs/Web/CSS/Descendant_combinator

          Для меня SCSS начисто умер после того, как столкнулся с таким (довольно распространённым) стилем написания кода:

          .class{
            .some-class{
            ...
              div{
                span{
                  a
                }
              }
            }
          }

          А мне понадобилось поменять цветовую схему. И оказалось, что в scss в принципе нет способа не копипастить вот эту лесенку))

          Ну это же дичь дикая! И повсеместно встречаемая...


          1. gmtd
            17.12.2023 14:52

            Цветовые темы меняются через CSS переменные, а не дубляжом всего кода

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


            1. Spaceoddity
              17.12.2023 14:52

              Цветовые темы меняются через CSS переменные, а не дубляжом всего кода

              Спасибо, я в курсе что и как делать. Я вам рассказываю про данность - надо поменять отдельные свойства. Копаться с рефакторингом подобного говнокода с выносом в переменные - без меня пожалуйста))

              Самое главное - где быстрый доступ к длинному контекстному селектору? А нету его!


            1. Spaceoddity
              17.12.2023 14:52

              //


          1. Akuma
            17.12.2023 14:52

            Конкретно здесь хз зачем так сделано. Вообще это делает примерно так:

            .item {
              .title {}
            
              .body {}
            
              .date {}
            
              .another {
                .child1 {}
            
                .child2 {}
              }
            }

            Получается гораздо удобнее. У вас как бы один элемент и вы его стилизуете, включая потомков. Не нужно каждый раз переписывать цепочку .item .another .child1 {}


            1. Spaceoddity
              17.12.2023 14:52

              Извините, мы в разной парадигме мыслим)) БЭМ мне всё-таки зашёл, поэтому:

              .item{}
              .item__title{}
              .item-body{}
              .item__date{}
              .item-another{}
              .item-another__child{} 
              .item-anoter__child_1{}
              .item-anoter__child_2{}

              Как-то так... Многие свойства (и даже правила), разумеется, можно опустить, поскольку наследование.


              1. Defersa
                17.12.2023 14:52

                У вас видимо в коде все селекторы внутри пустые, добавить по 4-5 строчек в каждые скобки и от красоты не останется следа


                1. Spaceoddity
                  17.12.2023 14:52

                  Причём здесь красота? Дело в удобстве))


                  1. Defersa
                    17.12.2023 14:52

                    А удобство извините меня в чем? Дублирование названий класса? Отсутствие иерархии? Назовите преимущества этого подхода


                    1. Spaceoddity
                      17.12.2023 14:52

                      Ну тут как бы вся соль в сути именования классов)) Где надо - там дублируется. Где не надо - нет))

                      Иерархия тут не просто есть, а очень мощная на самом деле ;) Можно привязываться как к структуре, там и к универсальным классам, глобальным.

                      Ну и вы как-то абстрактно набрасываете - приведите контрпример.


                      1. Defersa
                        17.12.2023 14:52

                        .item {
                        	&__title {}
                        	&__date {}
                        }
                        
                        .item-body {}
                        .item-another {
                        	&__child {}
                        	&__child_1 {}
                        	&__child_2 {}
                        }

                        А вот такое чем вас не устраивает? и БЭМ, и вложенность, и прочие плюшки



                      1. Defersa
                        17.12.2023 14:52

                        Вас почитать, так можно решить что все ООП вредно, инкапсуляция это проделки дьявола. Теперь у меня к вам только один вопрос - вы переменные js в глобальном скопе держите?


                      1. Spaceoddity
                        17.12.2023 14:52

                        О! Пошла подмена понятий и смешивание парадигм))

                        вы переменные js в глобальном скопе держите?

                        Если в этом есть нужда ;)

                        И я в курсе что такое "лексическое окружение в JS"))


              1. SerafimArts
                17.12.2023 14:52

                Что в свою очередь разворачивается в:

                .item {
                  &__title {}
                  &-body {}
                  &__date {}
                  &-another {
                    &__child {
                      &_1 {}
                      &_2 {}
                    }
                  }
                }


                1. Spaceoddity
                  17.12.2023 14:52

                  Зачем разворачивается?

                  Зачем мне вот эта лишняя привязка к структуре кода?)) Бритва Оккама, знаете ли. А ещё обычно как пойдёт ряд псевдоклассов и псевдоэлементов - в этой лапше не так-то и просто с ходу разобраться будет.


                  1. SerafimArts
                    17.12.2023 14:52

                    Думаю это дело привычки. Ориентироваться в иерархии в любом случае в варианте от SCSS попроще будет.


                    1. Spaceoddity
                      17.12.2023 14:52

                      Всё это с лихвой перекрывают такие "сюрпризы", как:

                      И да, я знаю как это фиксить, но с "ванильным CSS" у вас подобные проблемы в принципе не всплывут!


                    1. Spaceoddity
                      17.12.2023 14:52

                      Чем это проще???

                      Вы типа префикс заменяете переменной? Я не машина - мне комфортнее сразу видеть полное именование (в моём коде обычно единственного) класса. Я сразу могу сопоставить это именование с html-кодом (не структурой!). У меня вся необходимая иерархия сразу прописана в именовании класса. А "лесенки из табов" я точно так же могу фигачить - только как-то потребности не возникало до сих пор. Это первый шажок к потере "независимости и переиспользования".


    1. fransua
      17.12.2023 14:52

      У меня есть ощущение, что HTML и CSS считаются слишком сложными, поэтому вместо них имеем JSX и множество CSS библиотек. В этой статье как плюс, например, преподносится отсутствие каскадности: не нужно учить приоритеты селекторов.
      Для тех, кто знает HTML+CSS все эти поделки выглядят как попытка решить проблему, которой нет.


  1. Nurked
    17.12.2023 14:52

    И как это называть?

    Мало того, что мы под гнётом бесконечных звёздочек, пропихивает ещё одно усложнение жизни в виде непонятно зачем появившегося фреймворка, который в очередной раз заменит СSS (нет), там мы ещё делаем это в виде статьи, которая читается за две минуты.

    Это примерно как подойти к автомобилисту и сказать:

    Вы водите автомашин. Но говорить с вами я буду о 2020 Bimota Tesi H2. Это такой новый дизайн байков. У них передняя вилка не крепится напрямую к рулю. Ну так вот, такой подход - это круто. Покупайте 2020 Bimota Tesi H2.

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

    Может быть ему и было бы интересно посмотреть на эту Бимоту. Но проблема в том, что вы вообще нифига о них не рассказываете.

    Зачем мне нужно перегружать уже перегретый Webpack ещё одним плагином? Он и так уже тужится по пять минут, уминая в кучу весь тот ужас последних лет разработки. Мы сначала используем BeautifyJS для разработки, для того, чтобы запихнуть его в UglifyJS для ещё какой-то доработки, прежде чем это всё попадёт по конвееру на ещё какой-то парсер. Люди уже не помнят, как писать CSS, потому что везде есть SASS. Но и этого им мало, давайте запихнём то, что изначально было отдельным компонентом по определённым причинам в код.

    Нахрена? Ну, как же! Нам не надо будет бояться клэша названий классов. У нас же этих классов - миллион с хвостиком, их наплодило какое-то самообразование кода в пятьсот пятой строчке конфигурации вэбпака. Или реакта. Или CRA. Никто уже не помнит, но почему-то у нас на каждую кнопку вешается по 16 стилей. А давайте ещё сверху поставим компонент, который разработала компания с одним из самых сложных и запутанных программных продуктов в мире, которая пытается хоть как-то уладить ужасы абсолютно несовместимых интерфейсов и фреймворков, которые они-же сами наплодили.

    А давайте теперь поговорим о дебаге всего этого и того, как мы улаживаем очередную source-map. Что? Вас уже тошнит от того, что последний элемент в гриде на этом размере экрана для андроида вылезает за пределы бокса? Вы не можете ничего изменить, без полного ре-билда кода? Ну что же, мы тут не занимаемся анти-рвотными вещами. Мы как раз наоборот.

    Господи. Вы - не Фейсбук. У вас нет миллиона программистов, которые выдают на гора мегабайты кода каждый день. Вам не надо поддерживать уникальную инфраструктуру кода и приложений. Вам не надо выдумывать как обходить легальные ограничения разных стран. Вам не надо бороться с тем, что к вам заливают фотки терабайтами. Вам не нужны инструменты, которые были разработаны для обслуживания монстров!

    Большинство современных программных продуктов можно поддерживать с помощью двух CSS файлов. Самых обычных CSS файлов. Без надстроек и плагинов. Их можно даже подключать через HTML head. И можно даже не умереть без минификации всего этого.

    Самое прикольное - во всё это отлично и просто средствами самого CSS вставляется самая простая, но тем не менее отлично работающая система, поддерживающая разрые темы, в зависимости от настроек браузера. (То, что в Бутстрапе реашется только извращениями). А если вам лень написать простейший CSS-reset, то можно заставить ГПТ это сделать. Если уж слишком вам не жить без grid-layout то можно просто скачать один из пяти тысяч пятикилобайтных фреймворков, которые позволяют вам писать стили.

    Дизайнеры всё-равно будут переписывать стили вашего приложения. Вам не нужна вся база Бутстрапа.

    Господи, да откройте вы просто блокнот и напишите в нём

    body {
      padding: 0px;
      margin: 0px;
    }

    Зацените, не надо ни то, что компилировать, даже минифицировать не надо.

    Да сходите же, наконец-то на давно забытый https://csszengarden.com/pages/alldesigns/. Там всё ещё показывают как CSS работает без всех этих надстроек.

    Которые, конечно же влекут за собой дикие усложнения тестирования и дебага. Но об этом мы поговорим в другой раз. Потому что мы щас пока пишем фреймворк для фреймворка, чтобы он нам всё дебажил.


    1. Nurked
      17.12.2023 14:52

      Кстати. Ещё одна вещь.

      Ваша статья без большого куска скопипащщенго кода.

      Мой коммент к вашей статье:

      Просто банально показать, что вы даже пальцем не повели, чтобы постраться написать что-то. Более того, приглашение подареное НЛО, и купленный аккантв с одной только полу-дохлой публикацией.

      Как говорилось в старом недобром анекдоте:

      Вась, мы работаем в приличной компании, у нас толчки на каждом этаже. Нафига ты это пихаешь в сорц-контроль?


    1. Akuma
      17.12.2023 14:52

      О господи, адекватный человек на фронтэнде. Ловите его!


    1. alexnozer
      17.12.2023 14:52

      Просто снимаю шляпу перед автором этого комментария


    1. 0whitewolf0
      17.12.2023 14:52

      Полностью с вами согласен! Более того, css сам по себе прекрасно развивается, если бы нативно ещё разрешили писать через вложеные селекторы как в препроцессорах. То можно и от них было бы отказаться. Ещё лет 5 назад сколько нн пытался использовать функционал того же scss, в результате он только перегружал и мешал быстрому погружению. А православный БЭМ уже давно решил все проблемы с дальнейшим саппортом.

      Или вот если взять тот же тейлвинд, попался мне уже готовый проект, и разбираюсь в коде хотелось волосы рвать на голове. Я сделал вывод, что ребята придумаышие тейлвинд, решили переизобрести атрибут style на стероидах от которого все старались отказаться в начале 10х годов, и считалось дурным тоном его использование. А теперь ФБ решил выкатить вот это недоразумение.


  1. Spaceoddity
    17.12.2023 14:52

    • Предсказуемость – приоритизация селекторов в StyleX очень проста – всегда побеждает последний заданный стиль. Это значит, что можно забыть про каскадность.

    Почему писатели подобных либ постоянно норовят откреститься от одной из главных "фишек" CSS - каскада? Они реально не понимают как это работает?))

    Почему в цитируемом абзаце понятие "каскада" путается со "специфичностью"?

    Идём дальше:

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

    Могу себе в теории представить такую ситуацию (не смотря на дикую популярность изолированных стилей в последнее время). Но опять-таки, авторы не имеют понятия о специфичности в css? О том, как на ванильном CSS решить эту проблему одним щелчком пальцев?

    И сравнивая этот тезис с первой цитатой:

    всегда побеждает последний заданный стиль -> модули подгружались в разном порядке

    Сдаётся мне, проблема только усугубилась))

    • Комбинируемость – объекты стилей можно экспортировать и передавать в компоненты. При этом стили всегда будут вести себя предсказуемо.

    Какой-то высокопарный тезис, высосанный из пальца. А потенциально какую "непредсказуемость" можно ожидать? Модули будут подгружаться в разном порядке?))

    • Типизация – каждое css-свойство и переменная полностью типизированы, а мы можем использовать TypeScript или Flow, чтобы определить стили, передаваемые в компонент.

    А в чём вообще нужда типизировать CSS-свойства? Браузер и так в курсе разрешенных значений для этих свойств))

    Все в одном месте – библиотека поощряет определение стилей в том же файле, что и компонента.

    "Поощряет" = данность?

    Короче, понаплели, видать, там какой-то адовой лапши из CSS и JS и чтобы теперь разгрести эти авгиевы конюшни, пишут очередное "инвалидное кресло"...


    1. dopusteam
      17.12.2023 14:52

      Более того, в css тоже последний стиль иметь бОльший приоритет)


      1. Per_Ardua
        17.12.2023 14:52

        Не совсем так, ведь есть так называемая «специфичность», и обращение в css через 11 вложенных классов перебьет обращение по id.

        Но это надо очень сильно постараться (читать как «наверти**ячить»), чтобы встретить такой кейс в реальной разработке.


        1. dopusteam
          17.12.2023 14:52

          Ну да, я имел в виду, при прочих равных


        1. Spaceoddity
          17.12.2023 14:52

          Не совсем так, ведь специфичность не работает по принципу десятичных разрядов))

          UPD: Понимание этого аспекта, на самом деле, частенько имеет практическое применение - лишний класс всегда перебьёт сколько угодно длинную цепочку селекторов по тэгам.


          1. Per_Ardua
            17.12.2023 14:52

            Вы правы в том, что здесь не используется принцип десятичных разрядов. Однако другая разрядность всё же присутствует: https://habr.com/ru/articles/149791/


            1. jodaka
              17.12.2023 14:52

              Никаких других "разрядностей" нет. Был баг в браузерной реализации, который исправлен. По оригинальной ссылке можно самостоятельно проверить https://codepen.io/chriscoyier/pen/DKKmWE


            1. Spaceoddity
              17.12.2023 14:52

              Ну это просто баг. Точно так же лично я столкнулся с ограничениями для order как int32 - мне однажды показалась изящной идея осуществлять сортировку элементов по дате на голом css, путём привязки order к unix time stamp))


              1. Per_Ardua
                17.12.2023 14:52

                Понял, спасибо, буду знать!


    1. Duck7722
      17.12.2023 14:52

      Модули будут подгружаться в разном порядке?))

      Именно так. На каждый компонент реакта, свой css файл. Когда запускается приложение, компонент вставляет свои стили в порядке исполнения дерева реакта. Получается, что если сначала открыть страницу а, а потом страницу б, то страница а может теоретически влиять на страницу б.

      Да это именно понаделали, какой-то адовой лапши и страдают. Делают чтобы решить проблемы, что сделали где-то раньше.


  1. k12th
    17.12.2023 14:52

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


    1. Per_Ardua
      17.12.2023 14:52

      CSS-in-JS имеет свои приемущества, но думаю, многие согласятся, удобство разработчика не в этом списке)


    1. xsepsisx
      17.12.2023 14:52

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


  1. gmtd
    17.12.2023 14:52

    Фейсбуку очень надо как-то сделать ограничение области видимости (scope) CSS на один файл/компонент. Самые элегантное и эффективное решения для этого у Vue, через html атрибуты. Фейсбук не может взять это, ему надо придумать что-то свое, в итоге выходит вот это CSS-in-JS + HTML-in-JS.

    Что может выйти из рук людей, который грузили десятки мегабайт CSS для своего сайта?


    1. InfernoElegy
      17.12.2023 14:52

      scoped в vue это не самое элегантное решение. Все вычисление переносится в рантайм, из-за чего увеличиваются html и css файлы

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


      1. gmtd
        17.12.2023 14:52

        Откуда такие выводы?

        querySelector() работает чуть быстрее getElementById(). В Firefox последний вообще через первый эмулируется

        И по методу по Vue тоже были замеры - это работает тоже быстрей getElementById()


        1. Spaceoddity
          17.12.2023 14:52

          А причём здесь JS? Если надо смотреть насколько быстро CSSOM сгенерируется браузером? И как бы да, всегда считалось что доступ по айдишнику - быстрее всего, они обрабатываются в первую очередь.


  1. kiff
    17.12.2023 14:52

    Всем привет, пишу на чистом css, просто разделяя css по страницам сайта и имея один файл общих стилей. Также отдельные файлы стилей плагинов. Ну и отдельный файл адаптива.

    Пока верстка получается быстрее всех фреймворков..

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

    А еще я пишу на jQuery. И, что удивительно - все работает. Уверен, что модные фреймворки будут быстрее. Но я не пишу крипто биржы =(


    1. Kodzo
      17.12.2023 14:52

      Чем опытнее становишься, тем меньше тебе надо лишних инструментов.


    1. up7
      17.12.2023 14:52

      Для каждой задачи свой инструмент. Для очень многих вещей до сих пор хватает jQuery и файла стилей. Но для сложных задач фреймворки на фронте (да и на бэке конечно же) сильно выручают. Простой пример, на прошлой работе я писал (в команде) календарь заказов-событий для сети автомастерских. Если бы обновлять эту ленту, отслеживать события и сотни элементов с помощью jQuery - это был бы ад. А Vue - вообще никаких проблем.

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


      1. DizzyRide
        17.12.2023 14:52

        Приведу контрпример о вреде зоопарка фреймворков. Работал в министерстве. Собственные проекты делали на Symfony(PHP) + React и штат программистов нанимали под этот стек. Но в министерство часто приходили на доработку и сопровождение проекты с других ведомств. Чего там только не было - и node, и kotlin, и python - кто во что горазд. Даже если язык совпадал, то фреймворки всегда были разные. И всё это разнообразие часто доставалось мне.

        Что делать в этом случае? Держать зоопарк программистов под каждый фреймворк? Изучать каждый раз новый фреймворк ради каждого нового проекта?

        В последнем проекте (сайт федерального министерства) был самописный движок на основе экзотического Livestreet в беке и Vue во фронте. Бэк я освоил, потратив кучу времени. А под Vue так никого и не нашлось среди наших фронтов, которых нанимали на react. А самим изучать дополнительный фреймворк ради очередного проекта просто не было времени, и без того задач хватало.

        Такое обилие фреймворков часто вредит. Программистам трудно найти работу под свой стек, а работодателям - программистов под свой.


        1. gmtd
          17.12.2023 14:52

          Такое обилие фреймворков часто вредит.

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


          1. DizzyRide
            17.12.2023 14:52

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

            У нас то в отделе как раз и был стандарт - Symfony+React. Но проекты к нам часто попадали из разных организаций, в том числе неподконтрольных министерству. Какой уж там единый стандарт.

            Все таки отрасль крайне фрагментирована, огромное количество фреймворков и это часто вредит.

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


            1. gmtd
              17.12.2023 14:52

              А как вы собираетесь регулировать количество фреймворков и кто из них выживет? Их ведь на том же фронте на самом деле во много раз больше известной "тройки". Вы хотите Реакт с диктующим все правила типа StyleХ Фейсбуком?

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


              1. DizzyRide
                17.12.2023 14:52

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

                Строитель отделочник и электрик это разные профессии. А программист - одна. Вот предлагают мне проект со словами "ты ж программист, займись", при этом заказчик часто и слова такого - фреймворк - не знает. А там очередной новый фреймворк и передо мной выбор - или тратить время и деньги заказчика на изучение, или отказываться, оставляя себя без денег, а заказчика без выполненной работы. Никто не рад будет в такой ситуации, обе стороны получили проблемы.

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

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


                1. Spaceoddity
                  17.12.2023 14:52

                  Я фрилансер. Мне Вью выше крыши)) Т.е. я реактовский проект даже ни разу не открывал - не было нужды)) Спрос на любой фреймворк "большой тройки", кмк, сильно превышает предложение. Почему - это отдельный разговор. Но реальность такова.


  1. Ares_ekb
    17.12.2023 14:52

    Для меня минусы этой штуки и вообще CSS-in-JS вполне понятны:

    1. Вместо понятного и распространенного CSS добавляется лишняя абстракция. Нужно дополнительно напрягать мозг при написании и чтении стилей. И глядя на какой-нибудь `p: 10` пытаться понять что это значит. Не знаю есть ли конкретно в StyleX такие сокращения, но зачем мне изучать ещё один язык, если я уже знаю CSS?

    2. Изредка хочется использовать относительно сложные селекторы. В StyleX они видимо вообще не поддерживаются?

    3. Информации по CSS просто на много-много порядков больше, чем по очередному CSS-in-JS. Когда находишь какой-нибудь CSS-рецепт каждый раз нужно его транслировать в StyleX или наоборот если у тебя проблемы со стилями, то чтобы задать вопрос их нужно сначала перевести на CSS.

    4. Нельзя за 2 минуты создать HTML+CSS файлик в "блокноте" и по-быстрому отладить стили в браузере. Или поправить стиль в браузере и скопировать обратно

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

    6. Эти фреймвоки бесконечно меняются и запаришься каждый раз мигрировать стили

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

    8. В чем вообще смысл всё запихивать в один большой файл? С двумя маленькими файлами проще работать чем с одним большим

    Пытаюсь понять плюсы:

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

    2. Решение проблем с наложением стилей, специфичностью. У меня обычно этих проблем не возникает, я просто придерживаюсь единой схемы описания стилей. Но ещё есть же всякие CSS layer, scope, shadow DOM. Они не решают эту проблему?

    3. Людям сложно изучить CSS, а JS они уже знают. Непонятно что StyleX здесь упрощает, CSS всё равно придётся изучить, плюс добавится сложностей по постоянной трансляции стилей между CSS и StyleX в уме

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

    5. Поддержка стилей не только в браузере, но и в нативных приложениях. В какой доле проектов это требуется?

    В общем, к каким проблемам приведет StyleX я понимаю совершенно отчетливо, а преимущества как-то вообще не очевидны.


    1. nikfarce
      17.12.2023 14:52

      По минусам:

      1. Любой нормальный frontend разработчик знает про плагин Emmet и для него должны быть понятны сокращения "p15, m15" и все остальные.

      1. CodeSandbox? CodePen?

      2. В целом согласен, но переменные - штука очень полезная, если грамотно пользоваться.


      1. Ares_ekb
        17.12.2023 14:52

        1. Спасибо за ссылку! Когда-то давно краем глаза видел, но я не фуллтайм фронтендер, поэтому не отложилось в памяти. При написании кода это клево, но читать тяжело. Особенно если на проекте много людей которые только иногда заглядывают во фронт. Я имел в виду такие сокращения https://mui.com/system/getting-started/the-sx-prop/#spacing типа pt (который есть в Emmet), my (которого нет в Emmet), ... А потом MUI перейдёт на StyleX и опять переделывать все стили...

        1. Мне привычнее и проще это сделать в браузере. Для меня один из больших плюсов веб-разработки в том, что она практически ничего не требует кроме браузера и любого текстового редактора. Очень легко и просто делается минимальный пример, прямо в браузере можно его поправить, сразу виден результат. Для реальных проектов, наверное, да, без сложного тулинга не обойтись, но иногда ощущение что люди искусственно делают простые вещи сложными. А потом в какой-то момент начинают писать статьи, что мы тут подумали и решили отказаться от TypeScript. Я не удивлюсь если через какое-то время фб откажется от StyleX в пользу обычного CSS.

        2. Обычные переменные в CSS да, но когда всё это замешивается с JavaScript-кодом, то люди начинают там реализовывать просто лютейшую логику с кучей функций разбросанных по всему проекту. А в CSS у них такой возможности нет, приходится напрягать мозг, чтобы описать стили проще. Если в CSS-in-JS писать простые стили с простыми переменными без JavaScript-кода наверное это норм, но чем это лучше обычного CSS с переменными?..


        1. nikfarce
          17.12.2023 14:52

          Пожалуйста :) На счёт переменных JS в CSS полностью согласен.
          А на счёт CodeSandbox и CodePen не понял) Они же в браузере запускаются, как по мне это в разы быстрее и удобнее, чем в текстовом редакторе. Просто открыл сайт и пиши код, сразу всё работает. Хочешь Sass/SCSS/Less - тыкаешь настройки - добавляешь - работает)


      1. Spaceoddity
        17.12.2023 14:52

        1.Вы ещё на бутстрап сошлитесь)) Какие вообще точки пересечения у этих технологий? Эммет позволяет по быстрому html-структуру накидывать.

        1. Ограничение на пустом месте. В браузере все равно не поправите.

        2. Нет вопросов.


        1. nikfarce
          17.12.2023 14:52

          1. Причём тут bootstrap?

            "И глядя на какой-нибудь p: 10 пытаться понять что это значит.", в своём ответе я сослался на плагин Emmet, который позволяет написать p10, нажать tab и и получить padding: 10px;
            Т.е. я имею ввиду то что frontend-разработчик, использующий этот плагин спокойно будет понимать все эти сокращения (ну почти все, экзотические mt, mx и т.д. придётся всё-таки доучивать).

          1. О каких ограничениях речь? Я о возможностях написал)


          1. Spaceoddity
            17.12.2023 14:52

            1.Хотел ответить жёстче, но скажем так... Нет, я не считаю сколь-нибудь оправданным использованием Emmet для этих целей. Заучивать вот эту портянку? Спасибо нет, я не готов тратить ресурсы своего мозга на дублирование информации (я прекрасно ориентируюсь в синтаксисе "чистого CSS"). Я вообще css-код пишу в отдельном редакторе (js в vscode; html и css - в sublime, уж очень там годный автокомплит). Ну и я сходу вижу проблему в вашей интерпретации - px.

            4.Ну какие уж тут "возможности" - необходимость в интернет-доступе и целых два сервиса, вместо "в любом текстовом редакторе"?

            UPD: Какая жесть здесь "интеллектуальный markdown-редактор"


      1. DarthVictor
        17.12.2023 14:52

        Emmet - это просто способ управлениея автокомплитом. Давайте еще в исходниках Ctrl+F писать вместо RegExp. Его ещё больше народу знает.


        1. nikfarce
          17.12.2023 14:52

          Я знаю что такое Emmet, читайте выше


  1. Per_Ardua
    17.12.2023 14:52

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

    Новая либа фигачит всё в единый файл? И теперь все ваши хот-релоады и FCP (First Contentful Paint) идут по одному месту? Это никакая не недоработка, как вы по неопытности могли подумать! Это перфоманс и решение проблем с рантаймом!

    Либа применяет последние стили, словно к ним подписаны «!important»? И теперь цвета для ваших иконок вы обязаны передавать внутрь компонента иконок и возможности управления цветом из родителя у вас больше нет? Что за дичь, могли бы вы сказать! Но нет, это называется предсказуемость!

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


  1. gmtd
    17.12.2023 14:52

    Увидел только что на Youtube, просто оставлю этот билбоард здесь..

    Интересно, сколько ФБ выделяет на инфлюенсеров?


  1. nin-jin
    17.12.2023 14:52

    • Предсказуемость – приоритизация селекторов в StyleX очень проста – всегда побеждает последний заданный стиль. Это значит, что можно забыть про каскадность.

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

    • Перфоманс – библиотека на этапе компиляции с помощью Babel-плагина превращает JS в оптимизированный по размеру единый CSS файл, таким образом мы избегаем классических CSS-in-JS проблем с рантаймом.

    • Масштабируемость – гениальный Babel-плагин использует кэширование на уровне файлов и генерирует атомарные названия классов, за счет чего минимизируется размер бандла, а рост количества компонентов в приложении не сильно отражается на размере CSS файла.

    • Типизация – каждое css-свойство и переменная полностью типизированы, а мы можем использовать TypeScript или Flow, чтобы определить стили, передаваемые в компонент.


    1. nin-jin
      17.12.2023 14:52

      1. nin-jin
        17.12.2023 14:52


      1. qdanik
        17.12.2023 14:52

        Вы просто стоите друг друга...


  1. Akseley
    17.12.2023 14:52

    вроде очевидно, что скорее всего основное место применения SSR/Lazy loading.

    Но css-in-js подход - ????

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


  1. NIMAN
    17.12.2023 14:52

    Решительно не нравится спред оператор.

    1.Отвлекает и усложняет чтение кода.

    2.Начинающих разработчиков вгоняет в ступор, ведь prop drilling и неявная передача пропсов - антипаттерн.