ViteプラグインでtsconfigパスエイリアスがCSS/JSの解決に効かなかった問題を修正

tailwindlabs/tailwindcss

@tailwindcss/viteにおいてViteのresolve.tsconfigPaths: true@import@pluginに効かなかった根本原因は、ViteのリゾルバをaliasOnly: trueで呼び出していたことにあります。このPRではその値をfalseに変えることで、tsconfigパス解決を含む完全なVite解決パイプラインを通るようにしました。

背景

@tailwindcss/viteのCSSリゾルバとJSリゾルバはViteのリゾルバを呼び出す際にaliasOnly: trueを渡しており、これによりtsconfigパスの解決が機能しないという問題がありました。#19802で報告されたように、tsconfig.json"@themes/*": ["./src/themes/*"]を定義し、CSSで@import "@themes/custom.css"と記述しても、Viteのdev serverはCan't resolve '@themes/custom.css'エラーを返していました。

aliasOnly: trueが渡されると、ViteのcreateIdResolver@rollup/plugin-aliasプラグインのみを実行し、tsconfigパス解決を担う oxcリゾルバ をスキップします。そのため、resolve.aliasへの明示的なエントリ追加はワークアラウンドとして機能しましたが、resolve.tsconfigPaths: trueは一切効果がない状態でした。なお、Viteの内部CSSリゾルバ(css.ts)はaliasOnlyを省略(デフォルトfalse)して呼び出しており、完全な解決パイプラインを通過しています。

技術的な変更

packages/@tailwindcss-vite/src/index.tsにおいて、CSSリゾルバとJSリゾルバのaliasOnlyパラメータをtrueからfalseに変更しました。さらにCSSリゾルバでは、フルパイプラインによって非CSSファイルが解決されてしまうことを防ぐガード処理が追加されています。

変更前(Pre-environment API / Environment API):

// Pre-environment API
customCssResolver = (id: string, base: string) => cssResolver(id, base, true, isSSR)
customJsResolver = (id: string, base: string) => jsResolver(id, base, true, isSSR)

// Environment API
customCssResolver = (id: string, base: string) => cssResolver(env, id, base, true)
customJsResolver = (id: string, base: string) => jsResolver(env, id, base, true)

変更後(Pre-environment API / Environment API):

// Pre-environment API
customCssResolver = async (id: string, base: string) => {
  let resolved = await cssResolver(id, base, false, isSSR)
  if (resolved && !resolved.endsWith('.css')) return undefined
  return resolved
}
customJsResolver = (id: string, base: string) => jsResolver(id, base, false, isSSR)

// Environment API
customCssResolver = async (id: string, base: string) => {
  let resolved = await cssResolver(env, id, base, false)
  if (resolved && !resolved.endsWith('.css')) return undefined
  return resolved
}
customJsResolver = (id: string, base: string) => jsResolver(env, id, base, false)

CSSリゾルバにif (resolved && !resolved.endsWith('.css')) return undefinedというガード節が追加されている点が重要です。フルパイプラインでは非CSSファイルも解決対象になりうるため、解決結果が.css拡張子を持たない場合はundefinedを返してCSSリゾルバとしての責務を明示的に外れるようになっています。

設計判断

aliasOnlyfalseにすることで生じる副作用に対するガード処理の追加が、このPRの設計上の核心です。

aliasOnly: false(フルパイプライン)では@rollup/plugin-aliasが先に実行されるため、resolve.aliasの動作は引き続き保証されます。一方、フルパイプラインはCSSファイル以外も解決しうることから、CSSリゾルバが誤って非CSSリソースを返す可能性が生まれます。.endsWith('.css')によるフィルタリングはこの問題を最小限のコード変更で抑止しています。JSリゾルバにはこの追加ガードがない点も注目に値します。JSリゾルバの用途(@pluginなど)ではフルパイプラインの結果をそのまま使うことが想定されており、拡張子による絞り込みは不要と判断されています。

まとめ

たった1つのパラメータ変更(aliasOnly: truefalse)と、副作用を防ぐガード節の追加により、resolve.tsconfigPaths@import@pluginに対して正しく機能するようになりました。Viteのリゾルバ内部の動作を正確に把握した上で、最小限の変更で問題を根本解決した修正といえます。

記事メタデータ

Generated by:
Claude Sonnet 4.6 for DiffDaily
LLM Trace:
595e5690

この記事はAIによって自動生成されています。内容の正確性については、必ずソースコードやPRを確認してください。

品質レビュー結果

Review Status:
承認済み
Review Count:
1回
Reviewed by:
Gemini 2.5 Pro for DiffDaily

Review Criteria:

記事構成 ✓ PASS

Title, Context, Technical Detailの存在と明確さ

リード文(総論)→背景・技術詳細(各論)→まとめ(結論)という構成が明確で、ガイドラインに完全に準拠しています。

カスタムMarkdown構文 ✓ PASS

シンタックスハイライト・GitHubリンク記法の正確性

ファイル名付きシンタックスハイライトやGitHubのPR/Issueへのリンク記法が正しく使用されています。

対象読者への適合性 ✓ PASS

エンジニア向けの適切な技術レベルと表現

ViteやTailwind CSSの内部的な動作に言及しており、専門知識を持つエンジニアという対象読者に適した技術レベルで書かれています。

パラグラフ・ライティング ✓ PASS

トピックセンテンス・1段落1トピック・段落長

各セクションが総論→各論の構成になっており、各段落がトピックセンテンスで始まるなど、パラグラフ・ライティングの原則が守られており、非常に読みやすいです。

Diff内容との照合 ✓ PASS

コードブロックとDiff内容の一致

記事内のコードブロックは、提供されたDiff情報を正確に反映しています。変更前後のコードが分かりやすく提示されています。

技術用語の正確性 ✓ PASS

技術用語の正確な使用

`aliasOnly`, `oxc resolver`, `resolution pipeline`など、PRで使われている技術用語を正確に使用しています。

説明の技術的正確性 ✓ PASS

技術的主張の正確性と論理性

`aliasOnly: true`が問題の原因であるという説明や、ガード節の役割についての説明は、技術的に正確かつ論理的です。

事実の突合 ⚠ WARNING

PR情報による主張の裏付け(ハルシネーション検出)

記事の大部分はPR情報で裏付けられていますが、「Viteの内部CSSリゾルバはaliasOnlyを省略している」という記述はPR情報には含まれていません。これは外部調査に基づく事実であり、ハルシネーションではありませんが、原則としてPR情報に基づいた記述が求められます。

数値・固有名詞の確認 ✓ PASS

PR番号・コミットID・バージョン等の正確性

PR番号(#19803)や関連するIssue番号(#19802)が正確に記載されています。

タイトル・説明との一致 ✓ PASS

記事タイトル・説明とPR内容の一致

記事のタイトルは、PRの「fix(vite): resolve tsconfig paths in CSS and JS resolvers」という内容を的確に要約しています。

外部知識の正確性 ⚠ WARNING

PRに記載のない外部知識(LTS、サポート状況など)の不使用

「Viteの内部CSSリゾルバ(css.ts)はaliasOnlyを省略(デフォルトfalse)して呼び出している」という記述は、PR情報にない外部知識です。内容は正確で読者の理解を助けますが、ガイドラインではPR情報にない外部知識の追加は慎重になるべきです。

時間表現の正確性 ✓ PASS

時間表現がPR情報と一致しているか

記事内に時間表現の歪曲は見られず、事実を客観的に記述しています。