Vitest と PostCSS の相性問題解決ガイド

に公開

問題の概要

Next.js 15.3.4 + TailwindCSS v4 + Vitest v2.1.8 環境で、PostCSS設定とVitestテストランナーの間に互換性問題が発生していました。

発生していたエラー

  Failed to load PostCSS config: Invalid PostCSS Plugin found at: plugins[0]
  (@/postcss.config.mjs)
  TypeError: Invalid PostCSS Plugin found at: plugins[0]

関連GitHub Issue

根本原因

  1. PostCSS設定形式の競合
    • Next.js は ES Modules形式の postcss.config.mjs を使用
    • Vitest/Vite は一部のPostCSS プラグイン形式を正しく解析できない
    • TailwindCSS v4 の @tailwindcss/postcss プラグインとの相性問題
  2. 設定読み込み順序の問題
    • Vitest は独自のVite設定を使用するため、PostCSS設定の解釈が異なる
    • Next.js とは異なる方法でPostCSS設定を処理

解決方法

方法1: Vitest設定でPostCSS設定をオーバーライド(推奨)

vitest.config.ts
  import { defineConfig } from 'vitest/config'
  import path from 'path'

  export default defineConfig({
    test: {
      globals: true,
      environment: 'jsdom',
      setupFiles: ['./src/test/setup.ts'],
      css: {
        modules: {
          classNameStrategy: 'non-scoped'
        }
      }
    },
    resolve: {
      alias: {
        '@': path.resolve(__dirname, './src')
      }
    },
    // PostCSS設定をVitest用にオーバーライド
    css: {
      postcss: {
        plugins: [] // 空配列でテスト時のPostCSS処理をスキップ
      }
    }
  })

方法2: PostCSS設定ファイル形式の変更

  # 問題のある設定ファイルを削除
  rm postcss.config.mjs
postcss.config.json
  // postcss.config.json (新規作成)
  {
    "plugins": ["@tailwindcss/postcss"]
  }

実装した解決策

両方の方法を組み合わせて、最も堅牢な解決策を実装:

  1. Vitest設定でPostCSS制御: テスト実行時はCSS処理を最小限に
  2. JSON形式のPostCSS設定: Next.js ビルド時の互換性向上

ファイル構成

  ├── vitest.config.ts          # PostCSS オーバーライド設定
  ├── postcss.config.json       # JSON形式のPostCSS設定
  └── src/
      └── test/
          └── setup.ts           # CSS関連のテストセットアップ

設定詳細

vitest.config.ts の重要なポイント

vitest.config.ts
  export default defineConfig({
    test: {
      css: {
        modules: {
          classNameStrategy: 'non-scoped' // CSSモジュールを無効化
        }
      }
    },
    css: {
      postcss: {
        plugins: [] // PostCSS処理をスキップ
      }
    }
  })

postcss.config.json の設定

postcss.config.json
  {
    "plugins": ["@tailwindcss/postcss"]
  }

なぜこの解決策が有効か

  1. 設定分離: Next.js ビルドとVitestテストで異なるPostCSS処理
  2. 互換性向上: JSON形式はより幅広いツールで対応
  3. テスト最適化: CSS処理をスキップしてテスト実行速度向上
  4. 保守性: 将来のVite/Vitestアップデートに対応しやすい

追加のメリット

  • 高速テスト実行: CSS処理をスキップしてテスト速度向上
  • 安定性: PostCSS バージョンアップデートの影響を受けにくい
  • Next.js互換性: 本来の設定ファイルを保持してビルド互換性維持

この解決策により、Next.js + TailwindCSS + Vitestの組み合わせで完全に動作する開発環境が構築できました。

Discussion