Почему не работает Emotion: полная диагностика проблем

Ошибка @emotion/react module not found или стили, которые не применяются к компонентам, — самые частые симптомы того, что Emotion в проекте настроен неправильно. Библиотека Emotion — это CSS-in-JS решение для React, и сбои в её работе почти всегда связаны с установкой пакетов, конфигурацией сборщика или конфликтами версий.

В этой статье разберём основные причины, по которым Emotion перестаёт работать: от банального отсутствия зависимостей до тонких проблем с SSR и кешем сборки. Материал ориентирован на проекты с React, но общие принципы диагностики применимы и к другим сетапам.

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

Первая и самая вероятная причина — нужные пакеты просто не установлены или установлены не те. Для работы с React необходимы два пакета: @emotion/react и @emotion/styled. Установка только одного из них приводит к ошибкам вида Cannot find module '@emotion/styled'.

Проверьте секцию dependencies в файле package.json. Если пакетов там нет, установите их:

npm install @emotion/react @emotion/styled

Обратите внимание: старый пакет emotion (версии 10 и ниже) и современный @emotion/react (версия 11) — это разные API. Код, написанный под десятую версию с импортами из emotion или @emotion/core, не будет работать с одиннадцатой без миграции импортов.

  • 🔍 Откройте package.json и убедитесь, что оба пакета присутствуют в dependencies, а не только в devDependencies
  • 📦 Удалите node_modules и lock-файл, затем выполните чистую установку — это устраняет битые зависимости
  • 🔁 Проверьте, не установлены ли одновременно пакеты десятой и одиннадцатой версии — это частый источник конфликтов

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

Если стили применяются частично, пропадают после добавления новой библиотеки или приложение падает с ошибкой про несколько экземпляров Emotion — почти наверняка в дереве зависимостей оказалось две копии пакета. Это происходит, когда сторонняя UI-библиотека (например, компоненты на базе Emotion) тянет свою версию, отличную от вашей.

Диагностировать проблему можно командой npm ls @emotion/react. Если в выводе несколько разных версий, необходимо выровнять их. Для npm используется поле overrides в package.json, для yarn — resolutions.

⚠️ Внимание: принудительное выравнивание версий через overrides может сломать библиотеку, которая рассчитана на другую мажорную версию Emotion. После такого изменения обязательно прогоните приложение и проверьте рендеринг всех компонентов.
📊 С какой проблемой Emotion вы столкнулись?
Ошибка module not found
Стили не применяются
Конфликт версий пакетов
Проблемы с SSR/гидратацией

Стили определены, но не применяются

Ситуация, когда компонент рендерится без ошибок, но выглядит нестилизованным, обычно указывает на одну из трёх причин: неверный импорт, проблемы со специфичностью CSS или отсутствие нужного пресета в Babel/SWC.

Проверьте, откуда импортируются функции. Для css-пропа и styled корректные импорты выглядят так:

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

import styled from '@emotion/styled';

Если вы используете css-проп, необходимо, чтобы сборщик понимал этот синтаксис. В проектах на Create React App это работает из коробки при корректной версии пакетов, а в кастомных конфигурациях может потребоваться pragma-комментарий /** @jsxImportSource @emotion/react */ в начале файла или соответствующая настройка Babel. Точная настройка зависит от вашего сборщика — сверяйтесь с официальной документацией Emotion для вашего инструмента.

☑️ Диагностика неработающих стилей

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

Ещё один тонкий момент — порядок вставки стилей в head документа. Если глобальные CSS-файлы или другая библиотека вставляют стили после Emotion, они могут перекрывать его правила при равной специфичности. В таком случае проблема решается настройкой порядка стилей или повышением специфичности селекторов.

Проблемы с SSR и гидратацией

При серверном рендеринге (Next.js, Remix и подобных фреймворках) типичный симптом — предупреждение о несовпадении HTML при гидратации или мигание нестилизованного контента. Причина в том, что стили, сгенерированные на сервере, должны быть корректно извлечены и вставлены в HTML, а критический CSS — совпадать с тем, что вычислит клиент.

В Next.js настройка зависит от версии фреймворка и используемого роутера (pages или app directory). Универсальной инструкции нет: для app directory требуется отдельная конфигурация реестра стилей, которая описана в официальной документации Next.js и Emotion. Не копируйте конфигурацию для pages router в app router — они несовместимы.

Почему возникает рассинхронизация классов при SSR

Emotion генерирует имена классов на основе хеша содержимого стилей. Если на сервере и клиенте рендерятся разные деревья компонентов (например, из-за доступа к window или случайных значений), хеши не совпадут, и React выдаст ошибку гидратации. Проверьте компоненты на зависимость от браузерных API без защитных проверок.

Ошибки сборщика и кеша

Иногда Emotion «не работает» из-за проблем, вообще не связанных с библиотекой: устаревший кеш Webpack, Vite или Turbopack отдаёт старую сборку, в которой стилей ещё не было. Характерный признак — после изменения кода стили появляются и пропадают непредсказуемо.

Порядок действий в этом случае простой: остановите dev-сервер, удалите директории кеша (у Vite это node_modules/.vite, у Next.js — .next), затем запустите сборку заново. Для Vite также бывает необходимо добавить Emotion в optimizeDeps, если стили подгружаются из pre-bundled зависимостей с ошибками.

СимптомВероятная причинаПервое действие
Module not found: @emotion/reactПакет не установленУстановить оба пакета, перезапустить сервер
Стили есть в коде, но не в DOMНет pragma или настройки jsxImportSourceДобавить pragma в файл или настроить сборщик
Ошибка про несколько экземпляровДублирование версий в зависимостяхПроверить npm ls, выровнять версии
Мигание стилей при SSRНекорректное извлечение критического CSSНастроить реестр стилей по документации фреймворка
Стили пропадают после правокУстаревший кеш сборщикаОчистить кеш, пересобрать проект
⚠️ Внимание: не отключайте кеш сборщика насовсем и не применяйте «решения» из форумов вроде правки файлов внутри node_modules — такие изменения исчезнут при первой переустановке зависимостей и сделают проект неподдерживаемым.

Когда проблема в TypeScript и типах

Отдельный класс сбоев — ошибки типов: css-проп подсвечивается красным, сборка падает на этапе проверки типов, хотя в браузере всё работает. Это означает, что TypeScript не знает о расширении JSX от Emotion.

Необходимо убедиться, что в tsconfig.json корректно настроено поле jsxImportSource (значение @emotion/react) или что в проект подключены соответствующие типы. Конкретная настройка зависит от версии TypeScript и сборщика — проверьте актуальные рекомендации в документации Emotion. После правки tsconfig.json перезапустите TS-сервер в редакторе, иначе изменения не подхватятся.

Часто задаваемые вопросы

Чем отличаются пакеты emotion и @emotion/react?

Пакет emotion относится к десятой версии библиотеки, а @emotion/react — актуальная одиннадцатая версия с новым API. Они несовместимы по импортам, и смешивать их в одном проекте не следует.

Почему стили Emotion перекрываются моим обычным CSS?

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

Работает ли css-проп без настройки Babel?

Зависит от сборщика. В Create React App и некоторых фреймворках поддержка встроена, в кастомных конфигурациях требуется pragma-комментарий @jsxImportSource или настройка пресета. Сверяйтесь с документацией вашего инструмента сборки.

Что делать, если ошибка появляется только в production-сборке?

Проверьте, что пакеты находятся в dependencies, а не в devDependencies — при production-установке dev-зависимости пропускаются. Также соберите проект локально с чистым кешем, чтобы воспроизвести проблему.

Можно ли использовать Emotion вместе с Tailwind или Material-UI?

Да, но нужно учитывать порядок стилей и возможные дубли версий Emotion, которые тянут UI-библиотеки. Проверяйте дерево зависимостей и при необходимости выравнивайте версии через overrides или resolutions.