Tailwind CSSMiddleTechnical

Как мигрировать проект с Tailwind v3 на v4 CSS-first configuration?

Миграция с v3 на v4: заменить tailwind.config.js на @import "tailwindcss" в CSS, перенести кастомные токены в @theme {}, обновить PostCSS-плагин до @tailwindcss/postcss и проверить изменившиеся классы (shadow, blur, ring и др.).

Миграция с Tailwind v3 на v4: CSS-first конфигурация

Tailwind v4 полностью отказался от JS-конфига в пользу нативного CSS. Миграция включает несколько обязательных шагов.

Шаг 1: Обновление зависимостей

// package.json — новые пакеты
// было: tailwindcss, postcss, autoprefixer
// стало:
{
  "devDependencies": {
    "tailwindcss": "^4.0.0",
    "@tailwindcss/postcss": "^4.0.0"
  }
}
// postcss.config.js
module.exports = {
  plugins: {
    '@tailwindcss/postcss': {},
  },
};

Отдельный autoprefixer больше не нужен — Tailwind v4 встраивает prefixing самостоятельно.

Шаг 2: Замена конфигурационного файла

Файл tailwind.config.js удаляется. Вся конфигурация переезжает в CSS:

/* было: @tailwind base; @tailwind components; @tailwind utilities; */
/* стало: */
@import "tailwindcss";

/* Кастомные токены — замена theme.extend */
@theme {
  --color-brand: #6366f1;
  --color-surface: #f8f9fa;
  --font-sans: 'Inter', sans-serif;
  --radius-card: 0.75rem;
  --spacing-section: 4rem;
}

/* Подключение внешних источников классов */
@source "../node_modules/@myorg/ui/src/**/*.{js,ts,jsx,tsx}";

Шаг 3: Перенос theme.extend

В v3 кастомные значения добавлялись через theme.extend в JS. В v4 каждый токен становится CSS-переменной в блоке @theme:

// v3 tailwind.config.js
module.exports = {
  theme: {
    extend: {
      colors: {
        primary: { 500: '#6366f1', 600: '#4f46e5' },
      },
      borderRadius: {
        xl2: '1rem',
      },
    },
  },
};
/* v4 — эквивалент в CSS */
@theme {
  --color-primary-500: #6366f1;
  --color-primary-600: #4f46e5;
  --radius-xl2: 1rem;
}

Шаг 4: Изменившиеся утилиты

Ряд классов изменил поведение или переименован:

  • shadow → теперь shadow-sm по умолчанию немного другой (проверить визуально);
  • ring теперь ring-1 по умолчанию (было ring-3);
  • blurblur-sm изменил значение;
  • outline-none теперь также устанавливает outline-offset: 0;
  • Цветовая палитра расширена, slate/gray/zinc слегка скорректированы.

Шаг 5: Использование официального codemoda

npx @tailwindcss/upgrade@next

Скрипт обновляет package.json, postcss.config.js, генерирует CSS-конфиг и пытается перевести tailwind.config.js. После запуска обязательно проверить diff вручную.

Шаг 6: Плагины

Плагины v3 (typography, forms, aspect-ratio) имеют v4-совместимые версии:

@import "tailwindcss";
@plugin "@tailwindcss/typography";
@plugin "@tailwindcss/forms";

Подводные камни

  • Забытый @source для компонентных библиотек в node_modules — классы вырезаются в продакшне.
  • Нельзя смешивать tailwind.config.js и @theme — v4 игнорирует JS-конфиг по умолчанию.
  • Изменённые дефолтные значения ring и shadow ломают существующий UI без явных ошибок.
  • autoprefixer в postcss.config.js конфликтует с v4 — его нужно убрать.
  • Кастомные PostCSS-плагины могут не работать с новым порядком обработки.
  • Vite требует @tailwindcss/vite вместо PostCSS-плагина для лучшей производительности.
  • JIT-режим теперь единственный — нет fallback на полную сборку, несовместимые паттерны просто не работают.
  • Тёмная тема через darkMode: 'class' теперь настраивается через @variant dark (...) в CSS.

Common mistakes

  • Отвечать определением без production-сценария.
  • Не называть runtime boundary, security boundary или failure mode.
  • Игнорировать версию API, observability и тестовую проверку.

What the interviewer is testing

  • Объясняет механизм своими словами и без выдуманных API.
  • Называет реальные риски, диагностику и критерий корректности.
  • Связывает ответ с текущей документацией и миграционными ограничениями.

Sources

Related topics