`@variant`のみ使用するCSSファイルがViteプラグインでスキップされるバグを修正
@tailwindcss/viteのフィーチャー検出ビットマスクにFeatures.Variantsが欠落していたため、@variantのみを使用するCSSファイルが処理されずブラウザへ素通りしていました。1行の修正でこの検出漏れが解消されます。
背景
@tailwindcss/viteは、JSからインポートされたCSSファイルをTailwindが処理すべきかどうかを判定するフィーチャー検出の仕組みを持っています。ファイル内で使用されているディレクティブや機能をビットフラグとして検出し、Tailwind固有の機能が含まれていない場合はプレーンなCSSとして扱います。
今回の問題は、この検出チェックのビットマスクにFeatures.Variantsが含まれていなかったことで発生しました。@apply、theme()、ユーティリティクラスを一切使わず@variantだけを使用するCSSファイルは、Tailwindの処理対象と見なされずにスキップされます。結果として@variantディレクティブがブラウザにそのまま送出され、未知のat-ruleとして無視されてしまいます。
#19964に掲載された再現例では、@import "tailwindcss" と @custom-variant dark を持つメインのCSSと、@variant dark { ... } のみを含むoverrides.cssを組み合わせた構成が報告されています。overrides.cssはJS側から import './overrides.css' で読み込まれているにもかかわらず、@variant darkブロックが適用されない状態となります。
技術的な変更
packages/@tailwindcss-vite/src/index.ts内のRootクラスのフィーチャー検出ビットマスクにFeatures.Variantsを追加することで修正されています。
変更前:
if (
!(
this.compiler.features &
(Features.AtApply | Features.JsPluginCompat | Features.ThemeFunction | Features.Utilities)
)
) {
return false
}
変更後:
if (
!(
this.compiler.features &
(Features.AtApply |
Features.JsPluginCompat |
Features.ThemeFunction |
Features.Utilities |
Features.Variants)
)
) {
return false
}
このチェックは「いずれのフラグも立っていなければ処理をスキップする」というOR条件です。Features.Variantsを追加することで、@variantまたは@custom-variantのみを持つファイルもTailwindのコンパイルパスを通るようになります。既存の他フラグの動作には一切影響しません。
設計判断
既存のビットマスク構造を拡張する最小限の修正が採用されました。
フィーチャー検出の仕組み自体は変更されておらず、見落とされていたFeatures.Variantsフラグを列挙に加えるだけの1行相当の修正です。これは、バグ修正において「影響範囲を最小化しつつ正確に問題を解消する」という原則に沿った判断といえます。
まとめ
ビットマスクへのFeatures.Variantsの追加という小さな変更が、@variantのみを使うCSSファイルのサイレントスキップという実害のあるバグを修正します。フィーチャー検出に基づく処理パスの選択は効率的な設計ですが、新しいディレクティブを追加した際には検出条件の更新が必要となることを、本修正は改めて示しています。