Итак, продолжаем разбираться в buildtime CSS-in-JS. Начало — тут.
Сегодня я расскажу про библиотеку Vanilla Extract (VE), созданную компанией SEEK Group вместе с одним из авторов CSS Modules. В ридми на гитхабе подход VE описан как CSS Modules-in-TypeScript, и это правда: VE — это CSS Modules на стероидах, который полностью поддерживает TypeScript, темизацию из коробки и локальные CSS-переменные.
Вся работа со стилями в Vanilla Extract происходит в
.css.ts файлах. У VE есть готовые интеграции с популярными сборщиками для автоматического парсинга этих файлов.Базовый строительный блок VE — это функция
style. Каждый вызов style превращается в CSS-класс с уникальным хэшем, название которого экспортируется в JS в виде строки — ровно как в CSS Modules. Главное отличие в том, что style строго типизирована: VE использует набор типов CSSType, поэтому IDE будет давать подсказки и поможет избежать ошибок типизации.Вот как работает экстракция стилей из
.css.ts файла:import { style } from "@vanilla-extract/css";
export const container = style({
display: "flex"
});При компиляции это превратится в:
.styles_container__1hiof570 {
display: flex;
}export var container = "styles_container__1hiof570";
Сгенерированный класс можно использовать в разметке. VE работает с любым фреймворком и даже без него:
import { container } from "./styles.css.ts";
document.write(`
<section class="${container}">
...
</section>
`);Уже одной этой возможности достаточно для реализации любого по сложности проекта, но VE этим не ограничивается:
1️⃣ В пакете
@vanilla-extract/css встроена поддержка тем на основе CSS-переменных. При сборке VE сам генерирует для них уникальные хэши, и позволяет строить поверх них контракты с дизайн-токенами и безопасно использовать их в коде с поддержкой TS. Подробности про темизацию — в доке.2️⃣ У VE есть дополнительные пакеты для атомарных классов и вариативных компонентов. Это сильно расширяет возможности при построении дизайн-систем:
•
@vanilla-extract/sprinkles позволяет создавать утилитарные классы по типу Tailwind, но строго типизированные и только с тем набором свойств, который нужен в проекте. Это отличная база для библиотеки компонентов.•
@vanilla-extract/recipes позволяет описать конфиг для вариантов одного компонента. При этом recipes спокойно переиспользует sprinkles, так что можно собирать сложные комбинации без дублирования.Я не буду подробно расписывать все возможности VE, перечислю только ключевые: глобальные стили, сложные селекторы, медиа-выражения, container queries, layers и даже view transitions. Кроме того, нам доступна вся мощь JS/TS, а значит и любые вычисления, цветовые функции и утилиты. VE предоставляет свой пакет утилит
@vanilla-extract/css-utils, но можно использовать polished или писать свои функции.Для полноты картины, пройдёмся и по минусам VE:
• Кривая обучения:
sprinkles и recipes сначала могут быть непривычными, хотя по сути это Tailwind + cva.• CSS-селекторы — это простые строки, которые не типизированы, а работа с ними имеет свои ограничения и нюансы.
• На основе VE практически нет готовых UI-библиотек, и реализация собственных решений может быть слишком затратной.
Итог по VE. Это мощный современный инструмент для тех, кто хочет использовать всю силу JS/TS в стилизации и ценит хороший DX. Я бы рекомендовал Vanilla Extract командам с сильной экспертизой, которые строят собственную дизайн-систему для продукта с высокими требованиями к производительности и SSR.
Полезные ссылки для дальнейшего изучения:
• Документация VE
• Braid Design System — дизайн-система на VE от авторов
• How to build a styling foundation with vanilla-extract — гайд по реализации основных концепций для дизайн-системы на VE
➖➖➖
В следующем посте расскажу о своей UI-библиотеке Vanilla Sugar, которую я развиваю на основе Vanilla Extract.
Ставьте реакции — для меня это важно и вдохновляет писать дальше. И поделитесь в комментах: пробовали ли вы уже Vanilla Extract и что о нём думаете?