## Назначение интеграции Emotion и SWC
**Emotion** — популярная CSS-in-JS библиотека для React, предоставляющая инструменты для создания стилизованных компонентов, динамической генерации стилей и оптимизации работы с CSS на уровне JavaScript. При использовании классической конфигурации Emotion обычно применяется Babel-плагин `@emotion/babel-plugin`, который выполняет ряд преобразований исходного кода.
С появлением **SWC (Speedy Web Compiler)** возникла возможность заменить многие операции Babel значительно более быстрыми аналогами. Для проектов с большим количеством компонентов и развитой системой стилизации это позволяет существенно сократить время сборки и повысить производительность инструментов разработки.
Интеграция Emotion через SWC обеспечивает:
* автоматическую генерацию читаемых имён классов;
* поддержку source maps;
* оптимизацию шаблонных литералов;
* улучшенную отладку компонентов;
* ускоренную компиляцию по сравнению с Babel;
* поддержку SSR-сценариев Emotion.
---
## Как работает Emotion без дополнительных трансформаций
Базовый пример:
```jsx
import styled from "@emotion/styled";
const Button = styled.button`
padding: 12px 20px;
background: royalblue;
color: white;
`;
```
Во время выполнения Emotion:
1. Анализирует шаблонную строку.
2. Генерирует CSS.
3. Создаёт уникальный класс.
4. Добавляет стиль в DOM.
5. Привязывает класс к компоненту.
Без специальных преобразований сборщик практически не участвует в оптимизации такого кода.
---
## Роль SWC в обработке Emotion
SWC выполняет часть работы заранее во время компиляции.
Исходный код:
```jsx
const Button = styled.button`
color: red;
`;
```
После преобразований могут появляться дополнительные метаданные:
```jsx
const Button = styled.button(
"color:red;",
"label:Button;"
);
```
Emotion получает уже подготовленную информацию и тратит меньше ресурсов на этапе выполнения приложения.
Основные преимущества такого подхода:
| Возможность | Без SWC | Со SWC |
| ------------------- | ----------- | ------------- |
| Label генерация | Нет | Да |
| Source maps | Ограниченно | Да |
| Оптимизация CSS | Частично | Да |
| Скорость компиляции | Средняя | Очень высокая |
| Babel не требуется | Нет | Да |
---
## Включение поддержки Emotion в SWC
Настройка производится через файл `.swcrc`.
Базовая конфигурация:
```json
{
"jsc": {
"experimental": {
"plugins": []
},
"transform": {
"react": {
"runtime": "automatic"
}
}
}
}
```
Для Emotion используется специальный блок:
```json
{
"jsc": {
"transform": {
"react": {
"runtime": "automatic",
"importSource": "@emotion/react"
}
}
}
}
```
Параметр `importSource` сообщает компилятору о необходимости использовать JSX Runtime от Emotion.
---
## Новый JSX Runtime Emotion
Emotion предоставляет собственный JSX Runtime.
Вместо:
```jsx
/** @jsx jsx */
import { jsx } from "@emotion/react";
```
современный код может выглядеть следующим образом:
```jsx
import { css } from "@emotion/react";
function App() {
return (
Hello
);
}
```
При использовании SWC директивы `@jsx` больше не требуются.
Настройка:
```json
{
"jsc": {
"transform": {
"react": {
"runtime": "automatic",
"importSource": "@emotion/react"
}
}
}
}
```
---
## Поддержка свойства css
Одной из ключевых возможностей Emotion является специальный проп `css`.
Пример:
```jsx
Text
```
Либо:
```jsx
Text
```
SWC автоматически преобразует такие конструкции в вызовы внутренних API Emotion.
В результате браузер получает уже готовые классы, а не исходные объекты стилей.
---
## Автоматическая генерация label
Одной из наиболее полезных функций является генерация читаемых имён компонентов.
Исходный код:
```jsx
const SubmitButton = styled.button`
color: white;
`;
```
Без label итоговый класс может выглядеть так:
```html
css-1a2b3c
```
Со включённой генерацией:
```html
css-1a2b3c-SubmitButton
```
Подобные имена значительно упрощают:
* анализ DOM;
* отладку React-компонентов;
* поиск проблем со стилями;
* профилирование интерфейса.
---
## Настройка labelFormat
Emotion позволяет задавать собственный формат имён.
Пример конфигурации:
```json
{
"jsc": {
"experimental": {
"emotion": {
"labelFormat": "[local]"
}
}
}
}
```
Возможные шаблоны:
| Шаблон | Значение |
| -------------------- | ---------------------- |
| `[local]` | Имя компонента |
| `[filename]` | Имя файла |
| `[dirname]` | Каталог |
| `[local]-[filename]` | Комбинированный формат |
Пример:
```jsx
const Card = styled.div``;
```
Файл:
```text
ProfileCard.jsx
```
Результат:
```text
css-xyz-Card-ProfileCard
```
---
## Source Maps
Source Maps позволяют связывать сгенерированный CSS с исходным кодом приложения.
При возникновении проблемы в DevTools можно увидеть:
```css
color: red;
```
и сразу определить исходный файл:
```text
src/components/Button.jsx
```
В крупных проектах это значительно сокращает время поиска ошибок.
Настройка:
```json
{
"jsc": {
"experimental": {
"emotion": {
"sourceMap": true
}
}
}
}
```
---
## Оптимизация шаблонных литералов
Emotion активно использует template literals.
Пример:
```jsx
const Box = styled.div`
padding: 10px;
margin: 20px;
border-radius: 8px;
`;
```
SWC может анализировать содержимое шаблонной строки заранее и выполнять оптимизации ещё до запуска приложения.
Преимущества:
* меньше работы во время выполнения;
* меньше выделений памяти;
* ускорение гидратации;
* уменьшение нагрузки на клиентский JavaScript.
---
## Использование css-функции
Функция `css()` создаёт переиспользуемые наборы стилей.
```jsx
import { css } from "@emotion/react";
const primaryStyle = css`
color: white;
background: blue;
`;
```
Применение:
```jsx
```
SWC корректно обрабатывает подобные конструкции и сохраняет все возможности Emotion.
---
## Композиция стилей
Emotion позволяет объединять несколько наборов CSS.
```jsx
const baseStyle = css`
padding: 10px;
`;
const warningStyle = css`
background: orange;
`;
```
Использование:
```jsx
Warning
```
После компиляции создаются необходимые классы и выполняется их объединение.
---
## Styled Components через Emotion
Наиболее распространённый способ использования Emotion основан на API `styled`.
```jsx
import styled from "@emotion/styled";
const Card = styled.div`
padding: 20px;
border-radius: 12px;
`;
```
SWC анализирует такие объявления во время сборки и внедряет служебную информацию для последующей генерации классов.
---
## Динамические стили
Emotion поддерживает использование пропсов.
```jsx
const Button = styled.button`
background: ${(props) =>
props.primary ? "blue" : "gray"};
`;
```
Использование:
```jsx
```
Во время выполнения Emotion вычисляет только динамическую часть, тогда как статическая часть уже оптимизирована SWC.
---
## Работа с темами
Emotion содержит встроенную систему темизации.
Создание темы:
```jsx
const theme = {
colors: {
primary: "#2563eb",
danger: "#dc2626"
}
};
```
Подключение:
```jsx
import { ThemeProvider } from "@emotion/react";
```
Использование:
```jsx
const Button = styled.button`
background: ${(props) =>
props.theme.colors.primary};
`;
```
SWC не изменяет механизм темизации, но обеспечивает корректную трансформацию компонентов, использующих тему.
---
## Серверный рендеринг
Emotion поддерживает SSR через специализированные API.
Типичная схема:
```jsx
import createEmotionServer
from "@emotion/server/create-instance";
```
На сервере:
1. Выполняется рендер React.
2. Извлекаются критические стили.
3. CSS встраивается в HTML.
4. Клиент выполняет гидратацию.
SWC полностью совместим с подобным сценарием, поскольку его задача ограничивается этапом компиляции.
---
## Использование в Next.js
Современные версии Next.js могут работать через SWC без Babel.
Настройка:
```javascript
module.exports = {
compiler: {
emotion: true
}
};
```
После включения опции Next.js автоматически активирует встроенную поддержку Emotion через SWC.
Преимущества:
* отсутствие Babel-конфигурации;
* более быстрый запуск dev-сервера;
* ускоренные production-сборки;
* автоматическая генерация label;
* поддержка source maps.
---
## Использование в Vite
В проектах на Vite часто применяется SWC-плагин React.
Установка:
```bash
npm install @vitejs/plugin-react-swc
```
Конфигурация:
```javascript
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react-swc";
export default defineConfig({
plugins: [react()]
});
```
Для Emotion дополнительно настраивается `importSource`.
Пример:
```javascript
react({
jsxImportSource: "@emotion/react"
});
```
---
## Использование в Rspack
Rspack изначально использует SWC как основу трансформаций.
Настройка JSX Runtime:
```javascript
module.exports = {
builtins: {
react: {
importSource: "@emotion/react"
}
}
};
```
Подобная конфигурация позволяет использовать Emotion без подключения Babel.
---
## Сравнение Babel и SWC для Emotion
| Характеристика | Babel | SWC |
| ------------------------------------- | ------------ | ---------------- |
| Язык реализации | JavaScript | Rust |
| Скорость компиляции | Ниже | Значительно выше |
| Использование памяти | Выше | Ниже |
| Emotion поддержка | Через плагин | Встроенная |
| Время холодного старта | Выше | Ниже |
| Подходит для больших монорепозиториев | Ограниченно | Отлично |
Особенно заметна разница в проектах с тысячами React-компонентов и большим объёмом CSS-in-JS кода.
---
## Ограничения интеграции
Несмотря на высокий уровень совместимости, существуют особенности:
* некоторые Babel-плагины не имеют аналогов в SWC;
* нестандартные кастомные трансформации могут потребовать Babel;
* отдельные экспериментальные возможности Emotion появляются сначала в Babel-плагине;
* старые конфигурации с pragma-комментариями иногда требуют миграции на Automatic Runtime.
При разработке современных React-приложений эти ограничения встречаются редко.
---
## Практические рекомендации
**Для новых проектов**
```json
{
"jsc": {
"transform": {
"react": {
"runtime": "automatic",
"importSource": "@emotion/react"
}
}
}
}
```
**Для Next.js**
```javascript
compiler: {
emotion: true
}
```
**Для Vite**
```javascript
jsxImportSource: "@emotion/react"
```
**Для крупных приложений**
* включать source maps только в режиме разработки;
* использовать автоматическую генерацию label;
* выносить повторяющиеся стили в `css()`;
* комбинировать SSR и критический CSS;
* использовать SWC вместо Babel при отсутствии специфических Babel-зависимостей.
Такой подход позволяет получить максимально быструю сборку React-приложения при сохранении всех ключевых возможностей Emotion: динамических стилей, темизации, SSR, композиции CSS и удобной отладки.