ソースマップコメントの `=` をエスケープしてVitestの誤検知を修正
内部ソースマップのコメント生成において = を \x3d にエスケープすることで、Vitestがソースマップのパスを誤ってパースし発生していた警告を解消しました。
背景
テスト実行中に、VitestがViteのSSRモジュールロード処理でソースマップファイルを正しく解決できないという警告が発生していました。警告の内容は、${i} というリテラル文字列をファイルパスとして解釈しようとした結果、ENOENT: no such file or directory, open '.../${i}' というエラーが発生するというものです。
原因は、ソースマップのインラインコメントに含まれる = 記号にありました。sourceMappingURL=... という形式の文字列を Vite のソースマップパーサーが走査する際、= を区切り文字として解釈し、その後ろに続くURLの内容を誤ってパス変数(${i})として展開しようとしていたと考えられます。PRでは、この警告が Vitest のハングにも関係していた可能性も示唆されています。
技術的な変更
変更は packages/@tailwindcss-node/src/source-maps.ts の comment 関数1行のみで、= を Unicode エスケープ \x3d に置き換えることで対処しています。
変更前:
function comment(url: string) {
return `/*# sourceMappingURL=${url} */\n`
}
変更後:
function comment(url: string) {
return `/*# sourceMappingURL\x3d${url} */\n`
}
\x3d は ASCII コード 0x3D、すなわち = と等価であるため、生成されるCSSコメントの内容は変わりません。JavaScriptのテンプレートリテラル内でのみエスケープされた表現になるだけで、出力文字列としては従来通り /*# sourceMappingURL=app.css.map */ が得られます。
あわせて packages/@tailwindcss-node/src/source-maps.test.ts が新規追加され、comment('app.css.map') の戻り値が /*# sourceMappingURL=app.css.map */\n であることを明示的に検証するテストが導入されています。
import { expect, it } from 'vitest'
import { toSourceMap } from './source-maps'
it('should emit source maps', () => {
let map = toSourceMap('{"version":3,"sources":[],"names":[],"mappings":""}')
expect(map.comment('app.css.map')).toBe('/*# sourceMappingURL=app.css.map */\n')
})
設計判断
ソースコード上の表現を変更し、出力は維持するというアプローチが採用されました。
Viteのパーサーが = を誤検知するという問題に対し、パーサー側を修正するのではなく、生成側で回避する方針を取っています。\x3d はJavaScriptエンジンがパースする時点で = に展開されるため、出力されるCSSの仕様適合性は損なわれません。この修正は1文字の変更で済み、Tailwind CSSが生成するソースマップのフォーマット自体には一切影響しません。
まとめ
この変更は、テンプレートリテラル内の特定文字がツールチェーンのパーサーに誤解釈されるという、ツール間の相互作用に起因する問題をピンポイントに解消しています。出力を変えずにソースコードの表現のみを変える手法は、他のソースジェネレーターが同様の問題に直面した際の参考となるアプローチです。