非推奨ユーティリティのキャノニカライズルールを拡張
Tailwind CSS v4のアップグレードツールが、overflow-ellipsis・start-*・end-*系の非推奨ユーティリティを正規の名称へ自動変換できるようになりました。静的なマッピングに加えて正規表現による動的変換パターンを導入し、デフォルトのスペーシングスケール外の任意の値にも対応しています。
背景
Tailwind CSS v4では、いくつかのユーティリティクラスが正式に改名されました。start-*・end-*系は inset-s-*・inset-e-* に、overflow-ellipsis は text-ellipsis へと移行しています。アップグレードツールはこれらの非推奨ユーティリティを検出して正規名へ変換するキャノニカライズ機能を持っていますが、従来の実装では DEPRECATION_MAP に列挙された固定の文字列ペアのみが対象でした。
この方式では、start-4・start-8 のようにデフォルトのスペーシングスケール値として事前定義されているものは変換できる一方、start-123 や -end-px のように任意の値やネガティブバリアントは対象外でした。#19849 はこの制約を解消するために、パターンマッチングによる動的変換の仕組みを追加しています。
技術的な変更
DEPRECATION_TRANSFORMATION_MAP と tryDeprecatedUtilities 関数を新たに導入することで、静的・動的の2段階変換を実現しています。
変更前は deprecatedUtilities 関数が DEPRECATION_MAP を直接参照し、マッチしなければ即座に元の候補を返す単純な構造でした。
変更前:
const DEPRECATION_MAP = new Map([
['order-none', 'order-0'],
['break-words', 'wrap-break-word'],
])
// ...
let replacementString = DEPRECATION_MAP.get(targetCandidateString) ?? null
if (replacementString === null) return candidate
変更後:
const DEPRECATION_MAP = new Map([
['order-none', 'order-0'],
['break-words', 'wrap-break-word'],
['overflow-ellipsis', 'text-ellipsis'],
])
const DEPRECATION_TRANSFORMATION_MAP = new Map([
[/^(-)?start-(.*?)$/, '$1inset-s-$2'],
[/^(-)?end-(.*?)$/, '$1inset-e-$2'],
])
function* tryDeprecatedUtilities(candidate: string) {
// Try static replacements
let replacement = DEPRECATION_MAP.get(candidate)
if (replacement) yield replacement
// Try dynamic replacements
for (let [searchValue, replaceValue] of DEPRECATION_TRANSFORMATION_MAP) {
let replacement = candidate.replace(searchValue, replaceValue)
if (replacement === candidate) continue
yield replacement
}
}
tryDeprecatedUtilities はジェネレータ関数として実装されており、まず静的マップから完全一致を試み、次に正規表現パターンを順番に試します。正規表現 /^(-)?start-(.*?)$/ はオプショナルなマイナス記号と任意のサフィックスをキャプチャし、'$1inset-s-$2' で置換します。これにより start-full・start-auto・start-px・start-8・start-123 および各ネガティブバリアントがすべて1つのパターンでカバーされます。
また、collapseCandidates 関数冒頭にあった if (candidates.length <= 1) return candidates の早期リターンが削除されています。この変更により、候補が1件のみの場合でもキャノニカライズ処理が実行されるようになり、単独で使用された非推奨ユーティリティも変換対象になります。
設計判断
静的マップと動的パターンを分離した2層構造を採用することで、既存のシンプルな静的マッピングを維持しながら、パターンベースの変換を拡張可能な形で追加しています。
DEPRECATION_MAP と DEPRECATION_TRANSFORMATION_MAP を別々のデータ構造として定義することで、それぞれの役割が明確に分かれています。静的マップは完全一致の1対1変換に専念し、動的マップは正規表現による構造的なパターン変換を担います。ジェネレータ関数 tryDeprecatedUtilities がこの2つの変換戦略を統一したインターフェースで提供し、呼び出し側は変換候補を順に試すだけでよい設計です。
正規表現のパターン $1inset-s-$2 でオプショナルキャプチャグループを使うことで、ネガティブバリアント(-start-8 → -inset-s-8)とポジティブバリアント(start-8 → inset-s-8)を同一のルールで処理しています。新たな非推奨パターンが生じた場合も、DEPRECATION_TRANSFORMATION_MAP にエントリを追加するだけで対応できる拡張性を持ちます。
まとめ
本PRは、固定値マッピングだけでは対応しきれなかった任意値・ネガティブバリアントのキャノニカライズを、正規表現による動的パターンマッチングで解決した変更です。2層構造の変換設計により、既存のシンプルさを保ちつつ将来の非推奨ルール追加にも対応できる拡張性を獲得しています。