Не работает Emotion: диагностика и решение проблем

Если стили Emotion не применяются, а в консоли браузера появляется ошибка вида Cannot read properties of undefined или предупреждение о неизвестной пропсе css, первым делом проверьте, какой именно пакет установлен в проекте: @emotion/react и @emotion/styled — это два разных пакета, и импорт из одного при использовании API другого приводит к тому, что стили молча игнорируются. Откройте package.json и сверьте импорты в файлах компонентов.

Emotion — популярная CSS-in-JS библиотека для React, и причины её отказа почти всегда сводятся к нескольким типовым сценариям: неправильная настройка Babel или JSX-трансформации, конфликт версий, дублирование пакетов в зависимостях или особенности сборщика. Ниже разберём каждую причину и порядок безопасной диагностики.

Проверка установки и импортов

Начните с базовой проверки зависимостей. Выполните в терминале команду, которая покажет установленные версии:

npm ls @emotion/react @emotion/styled

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

Далее проверьте импорты в коде. Для пропса css нужен пакет @emotion/react, а для создания стилизованных компонентов — @emotion/styled:

import { css } from '@emotion/react';

import styled from '@emotion/styled';

  • 🔍 Убедитесь, что оба пакета установлены, если используете оба API
  • 📦 Проверьте, что импорты не идут из устаревших пакетов emotion или @emotion/core — это API старых мажорных версий
  • 🧹 После изменения зависимостей удалите node_modules и файл блокировки, затем переустановите пакеты
📊 Что именно не работает у вас в Emotion?
Пропс css не применяет стили
styled-компоненты рендерятся без стилей
Ошибка при сборке проекта
Стили пропадают в production-сборке

Проблема с пропсом css и JSX-трансформацией

Самый частый сценарий: пропс css передаётся в элемент, но стили не применяются, а в DOM попадает атрибут css="[object Object]". Причина — стандартная JSX-трансформация не знает о пропсе css, его обрабатывает специальный jsx pragma от Emotion.

Есть несколько способов включить поддержку. В современных версиях React с автоматическим JSX-рантаймом достаточно указать pragma в комментарии в начале файла:

/** @jsxImportSource @emotion/react */

Альтернатива — настроить пресет Babel @emotion/babel-preset-css-prop либо плагин @emotion/babel-plugin, если он предусмотрен вашей конфигурацией. Точный набор плагинов зависит от версии Emotion и сборщика, поэтому сверяйтесь с официальной документацией установленной у вас мажорной версии.

⚠️ Внимание: комментарий @jsxImportSource должен стоять в самом начале файла, до всех импортов. Если разместить его ниже, трансформатор его проигнорирует, и диагностика причины затянется.

Конфликты версий и дублирование пакетов

Если проект использует UI-библиотеку, построенную на Emotion (например, некоторые версии MUI зависят от Emotion как от движка стилей), в дереве зависимостей может оказаться две копии @emotion/react. Это приводит к непредсказуемому поведению: кэш стилей создаётся дважды, контексты темы не совпадают, стили применяются частично.

Диагностировать дублирование помогает вывод npm ls, упомянутый выше. Если обнаружены разные версии, варианты решения:

  • 🔄 Обновите все зависящие от Emotion пакеты до совместимых версий
  • 📌 В package.json зафиксируйте единую версию через поле resolutions (Yarn) или overrides (npm)
  • 🧩 Проверьте, что Emotion указан в dependencies, а не только в devDependencies — иначе в production-сборке пакета может не оказаться

Настройка Babel и сборщика

Плагин @emotion/babel-plugin не обязателен для базовой работы, но без него не будут работать некоторые возможности: автоматические label-имена классов, минификация стилей, оптимизация source maps. Если у вас «не работает Emotion» в части дебага или имен классов — проверьте наличие плагина в конфигурации.

Пример секции в .babelrc или babel.config.js:

{

"plugins": ["@emotion/babel-plugin"]

}

Для проектов на Vite поддержка Emotion включается через настройку плагина React — там указывается jsxImportSource. В Next.js поведение зависит от версии фреймворка: в одних достаточно установить пакеты, в других требуется настройка компилятора. Поскольку конфигурация различается между версиями, сверяйтесь с документацией именно вашего стека, а не копируйте чужой конфиг целиком.

СимптомВероятная причинаЧто проверить
Атрибут css в DOM как строкаНе настроен jsx pragmaКомментарий @jsxImportSource в начале файла
Стили применяются частичноДве копии @emotion/reactВывод npm ls, overrides в package.json
Ошибка при импорте styledНе установлен @emotion/styledСписок зависимостей проекта
Стили есть в dev, нет в buildEmotion в devDependenciesСекция dependencies в package.json
Нет читаемых имён классовОтсутствует babel-плагинКонфигурация Babel

Проблемы с SSR и серверным рендерингом

При серверном рендеринге стили Emotion должны быть извлечены и вставлены в HTML на сервере, иначе страница отрисуется без стилей до гидратации. Если у вас «мигает» нестилизованный контент или стили пропадают при SSR — проверьте интеграцию с вашим фреймворком.

Порядок действий зависит от фреймворка: для Next.js существуют официальные примеры интеграции Emotion, для собственного SSR-сетапа используется API извлечения критических стилей. Несовпадение кэша Emotion между сервером и клиентом — типичная причина рассинхронизации классов и предупреждений о hydration mismatch.

Подробнее о кэше Emotion

Emotion использует объект кэша (createCache), который определяет, куда вставляются стили и с какими префиксами. При SSR кэш на сервере и клиенте должен быть сконфигурирован одинаково — включая ключ (key) и настройки stylis-плагинов. Если ключи различаются, сгенерированные на сервере классы не совпадут с клиентскими.

Ошибки типов в TypeScript

В TypeScript-проектах отдельная категория проблем — пропс css не распознаётся компилятором, хотя в рантайме всё работает. Это означает, что типы Emotion не подключены к JSX-неймспейсу. Обычно помогает проверка, что используется @jsxImportSource (он подтягивает типы автоматически), либо явное расширение типов согласно документации вашей версии.

Ещё один сценарий — конфликт типов при использовании styled с кастомными пропсами. Если TypeScript ругается на передачу пропсов в styled-компонент, типизируйте компонент явно через дженерик и при необходимости фильтруйте пропсы опцией shouldForwardProp, чтобы они не попадали в DOM.

⚠️ Внимание: не подавляйте ошибки типов через @ts-ignore или приведение к any — это маскирует реальную проблему конфигурации, которая проявится позже при обновлении зависимостей.

Пошаговая диагностика: чек-лист

Если ничего из перечисленного не помогло, пройдите по чек-листу последовательно — он покрывает типовые причины отказа Emotion от простых к сложным.

☑️ Диагностика Emotion

Выполнено: 0 / 6

После каждого шага перезапускайте dev-сервер и проверяйте результат в браузере с открытой консолью — предупреждения Emotion часто содержат прямое указание на причину.

Частые вопросы

Почему пропс css отображается в DOM как атрибут?

Потому что JSX-трансформация не обрабатывает его как пропс Emotion. Добавьте комментарий /** @jsxImportSource @emotion/react */ в начало файла или настройте Babel-пресет Emotion для всего проекта.

Работают ли вместе Emotion и Tailwind?

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

Стили есть в dev-режиме, но пропадают в production. Что делать?

Проверьте, что пакеты Emotion находятся в dependencies, а не в devDependencies, очистите кэш сборщика и пересоберите проект. Также убедитесь, что минификация не вырезает стили — это бывает при нестандартной конфигурации сборки.

Нужен ли babel-плагин для работы Emotion?

Для базовой работы — нет, достаточно правильной JSX-трансформации. Плагин добавляет удобства: читаемые имена классов, минификацию стилей и улучшенные source maps, что упрощает отладку.

Как понять, что в проекте две копии Emotion?

Выполните npm ls @emotion/react — если в дереве вывода одна и та же зависимость встречается с разными версиями, копий несколько. Признаки в рантайме: частично применяющиеся стили, неработающая тема, дублирование тегов style в head.