Не выбрасывайте токены вашей дизайн-системы!

Вы решили изменить стили своей системы дизайна с LESS или SASS на подход CSS-in-JS из-за его многочисленных преимуществ, но вы столкнулся с проблемой.

Проблема

Ваша существующая система дизайна построена на библиотеке токенов дизайна, которые предварительно обрабатываются в LESS или SASS, чтобы сделать ваши стили CSS согласованными. Весь внешний вид вашей дизайн-системы основан на этих токенах, а с CSS-in-JS вы потеряли возможность использовать свои токены и выполнять их предварительную обработку.

Или у тебя?!

Один из способов жить

Давайте создадим небольшой пример и скажем, что наши токены выглядят так:

Одна вещь, которую мы МОЖЕМ сделать для решения нашей проблемы, заключается в следующем: создать и распространить пакет токенов, который будет использоваться в качестве зависимости для наших компонентов.

Допустим, это файл styles.js для нашего компонента banner, который импортирует этот пакет tokens:

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

Например, предположим, что команда использует v1.0.0 наших пакетов button и banner, которые оба используют v1.0.0 нашего пакета tokens в качестве зависимости.

Теперь эта команда решает обновить свой пакет banner до версии 1.1.0, который имеет обновленную зависимость от tokens версии 1.1.0.

Нередко можно дважды увидеть пакет tokens в комплекте этой команды. Представьте, если бы эта команда потребляла очень реалистичное количество, скажем, 20 пакетов вместо двух!

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

Настоящее решение

Мы можем предварительно обработать наши файлы CSS-in-JS с помощью css-in-js-preprocessor:



Он работает, используя ту же концепцию, с которой вы знакомы для LESS и SASS. Чтобы проиллюстрировать это, давайте изменим наш предыдущий пример:

Прежде всего, вам нужно установить css-in-js-preprocessor:

npm i css-in-js-preprocessor --save-dev

На этот раз наши токены будут жить в файле нашего проекта с именем my-tokens.json. Содержимое такое же, как и выше, только в файле, а не в пакете. Теперь мы изменим импорт нашего файла banner style.js, чтобы импортировать локальный файл:

Далее происходит волшебство. Мы собираемся создать файл style-preprocess.js, который будет выполняться в конце нашего процесса компиляции или сборки файлов, полученных в результате этого процесса:

Как вы выполняете этот файл в своем конвейере, зависит от вас, но мы обычно делаем это как часть скрипта компиляции, который мы выполняем как команду NPM в нашем package.json. :

"scripts": {
  "compile": "tsc && node ./style-preprocess.js"
}

Команда tsc предназначена для компиляции TypeScript. Если вы не используете TypeScript, скорее всего, вы используете Babel. Просто добавьте наш новый скрипт в конец того, что вы делаете, чтобы транспилировать ваш JavaScript.

ПРЕДУПРЕЖДЕНИЕ. Убедитесь, что вы запускаете сценарий для файлов, которые выводит процесс сборки, а не для ваших исходных файлов!

Мы должны увидеть, что наш файл styles.js изменился по сравнению с этим:

…к этому:

БАМ!

Мы успешно обработали наши файлы, заменив ссылки на токены фактическими значениями токенов! Мало того, css-in-js-preprocessor удалил импорт токенов из верхней части нашего файла!

Наш исходный файл для styles.js должен остаться без изменений и использовать токены. Преимущество такое же, как и в случае с LESS и SASS: если значение токена когда-либо изменится, мы просто перекомпилируем, и наш вывод теперь будет иметь обновленные значения.

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

Несколько файлов

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

Пользовательские препроцессоры

Вы обнаружите, что css-in-js-preprocessor еще мощнее и может использоваться многими другими способами и для многих других целей, чем наши старые аналоги LESS и SASS. Это потому, что мы можем внедрить наши собственные препроцессоры.

Давайте создадим два пользовательских препроцессора и добавим их в утилиту preprocessor. Это заменяет строки № 8–9 выше:

Если мы повторно запустим нашу компиляцию, мы должны увидеть, что наш файл styles.js изменился на это:

Мы видим, что padding было преобразовано в margin, а отметка даты/времени была добавлена ​​в качестве комментария к нижней части файла из-за наших пользовательских дополнений.

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

Больше, чем просто файлы CSS-in-JS

Поскольку мы можем добавлять свои собственные препроцессоры, мы можем использовать их не только для наших токенов дизайна и CSS-in-JS.

Например, я часто создаю константу version в файлах своих компонентов, которая добавляется к самому внешнему узлу DOM компонента в качестве атрибута данных, когда он находится в режиме отладки. Эта константа версии обновляется во время моего процесса бампинга и работает с файлами .jsx и .tsx.

Давайте посмотрим, как это делают LESS и SASS!

Вперед

Теперь мы можем перенести нашу систему дизайна в новую эру CSS-in-JS, воспользоваться всеми ее преимуществами, избавиться от недостатков и получить дополнительную мощность и гибкость!