✅
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
根本原因
- PostCSS設定形式の競合
- Next.js は ES Modules形式の postcss.config.mjs を使用
- Vitest/Vite は一部のPostCSS プラグイン形式を正しく解析できない
- TailwindCSS v4 の @tailwindcss/postcss プラグインとの相性問題
- 設定読み込み順序の問題
- 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"]
}
実装した解決策
両方の方法を組み合わせて、最も堅牢な解決策を実装:
- Vitest設定でPostCSS制御: テスト実行時はCSS処理を最小限に
- 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"]
}
なぜこの解決策が有効か
- 設定分離: Next.js ビルドとVitestテストで異なるPostCSS処理
- 互換性向上: JSON形式はより幅広いツールで対応
- テスト最適化: CSS処理をスキップしてテスト実行速度向上
- 保守性: 将来のVite/Vitestアップデートに対応しやすい
追加のメリット
- 高速テスト実行: CSS処理をスキップしてテスト速度向上
- 安定性: PostCSS バージョンアップデートの影響を受けにくい
- Next.js互換性: 本来の設定ファイルを保持してビルド互換性維持
この解決策により、Next.js + TailwindCSS + Vitestの組み合わせで完全に動作する開発環境が構築できました。
Discussion