Ошибка @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. После такого изменения обязательно прогоните приложение и проверьте рендеринг всех компонентов.
Стили определены, но не применяются
Ситуация, когда компонент рендерится без ошибок, но выглядит нестилизованным, обычно указывает на одну из трёх причин: неверный импорт, проблемы со специфичностью 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 для вашего инструмента.
☑️ Диагностика неработающих стилей
Ещё один тонкий момент — порядок вставки стилей в 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.