📚

Tailwind CSS v4アップデートのリアルな実務課題と対策

に公開

はじめに

株式会社ASSIGNでWebフロント開発を担当している中水です。

先日、弊社で開発しているプロダクトでTailwind CSS v4へのアップデートを実施しました。
v4が提供する新機能に期待してアップデート作業に取り掛かりましたが、いざ進めてみると、いくつかの予期しない問題に直面しました。
実プロダクトでのv4アップデート事例は自分が調べた範囲では見当たらなかったため、これからv4への移行を考えている方にとって少しでも参考になる情報をお届けできればと思います。

アップデートの背景

今回、v4へのアップデートに踏み切った理由は、主に2つの大きなメリットを享受するためです。

1つ目はパフォーマンスの向上です。v4では新しい高性能エンジン(Oxide)が導入され、Rustベースの新実装により、旧バージョンと比較してビルド時間が大幅に短縮されています。

2つ目は開発体験の向上です。v4では、すべてのデザイントークンがデフォルトでCSS変数として提供されるため、Configファイルを編集することなく柔軟に値を管理できるようになりました。これにより、例えばFigmaで定義したデザイントークンとTailwind CSSを簡単に連携させ、デザインとコードの整合性を保ちながら開発を進めることが可能になりました。現在弊社ではデザインシステムの構築を進めており、この点は大きな助けとなると判断しました。
(デザインシステム構築については、別の記事で触れる予定です。)

想定していた進め方

正直に言うと、当初は今回のアップデートをかなり楽観的に捉えていました。
想定していた進め方は下記の通りです。

  1. 自動アップグレードツールの実行

    • 公式の移行ツールを使えば、ほとんどのクラスは自動で置き換わるだろうと考えていました。
  2. 自動変換後のUIの目視確認

    • 変換後のUIに予期せぬスタイル崩れがないかを確認するだけで済むと見込んでいました。
  3. 必要に応じて手動でコード修正

    • 大きな問題は起きず、少数の修正だけで移行は完了するだろうと想定していました。

アップデート作業で直面した問題

当初の見通しとは異なり、実際の作業ではいくつもの問題に直面しました。

1. 影響範囲の事前調査不足

「まずはアップグレードツールを試してみよう」と軽い気持ちで下記コマンドを実行しました。

npx @tailwindcss/upgrade

確認したところ、変更されたファイル数は180件を超えていました。

アップグレードツール実行直後の変更ファイル数

弊社プロダクトでは多くのUIコンポーネントがユーティリティクラスに依存しており、スタイルの共通化が不十分だったため、影響範囲が広がってしまいました。

2. ツールで対応できなかったユーティリティクラスの変更

アップグレードツールは多くのユーティリティクラスを自動で書き換えてくれましたが、一部のクラスは自動変換されず、手動で修正が必要でした。
例えば、v3では個別のユーティリティクラスだったものが、v4では名前が変更されたり、既存のユーティリティと組み合わせて使われるようになりました。

手動で修正が必要なユーティリティクラス

カテゴリ v3.xのクラス名 v4.0のクラス名
シャドウ shadow-sm
shadow
shadow-xs
shadow-sm
リング ring ring-3
アウトライン outline-none outline-hidden
不透明度 bg-opacity-* bg-black/50 のように / を使った表現

カテゴリごとの変更内容

  • シャドウ
    • スケールが変更
      • shadow-smshadow-xs
      • shadowshadow-sm
  • リング
    • デフォルトの幅が 1px に変更
    • v3で3pxを想定していた場合はring-3と明示的に記述する必要あり
  • アウトライン
    • v3のoutline-noneoutline-hiddenに改名
    • outline-noneoutline-style: noneで完全に非表示
  • 不透明度
    • 指定方法が変更され、bg-black/50 のように / 記法を使用

特に、弊社プロダクト内では不透明度のユーティリティクラスを多用していたため、手動での修正後、各画面でのスタイル崩れを確認する作業にかなりの時間を要しました。

3. カスタムアニメーションが動作しない問題

v4へ移行後、configファイル内で定義していたカスタムアニメーションが動作しない問題が発生しました。
アップグレードガイドを確認しても、この問題に関する記述は見当たりませんでしたが、GitHubのIssueを調べてみると、アニメーション名がケバブケースで記述されていないと機能しないという情報にたどり着きました。

https://github.com/tailwindlabs/tailwindcss/issues/16092

// v3.x では動くが、v4.0 では動かない定義例(camelCase)
animation: {
  // `slideUp` はケバブケースではないため v4 では無視される
  slideUp: 'slideUp 0.5s ease-out forwards',
},
// v4 での修正例(kebab-case)
animation: {
  'slide-up': 'slide-up 0.5s ease-out forwards',
},

このように、公式ドキュメントには明記されていない細かな変更点を見落としていたことでデバッグに予想以上の時間を要しました。

反省点と改善策

今回のアップデート作業が難航したのは、一言で言えば「準備不足と検証の不十分さ」でした。
技術的なメリット、例えばパフォーマンス向上や開発体験の改善に過剰に注目し、アップデートに伴うリスク評価が不十分だったと痛感しています。

1. 事前調査を徹底する

「ツールを使えば大丈夫」という楽観的な考えは捨て、事前に検証ブランチを切り、影響範囲を把握することが不可欠だと痛感しました。問題点を事前に把握し、影響範囲を見積もった上で、移行計画を策定するプロセスを必ず経るようにします。

2. スタイルの共通化を進める

手動修正が困難だった最大の原因は、JSX/TSX内でユーティリティクラスを多用していたことでした。多くのスタイルが個別に記述されていたため、アップデート作業時に同じスタイルを何度も修正する必要があり、作業が増えてしまいました。
今後は、共通のスタイルをコンポーネント化し、@applyを活用してスタイルの一貫性を保つことを目指します。よく使うスタイルやデザインパターンをコンポーネントとしてまとめ、変更が必要な場合は一箇所で修正できるようにします。

3. コミュニティ情報の活用

公式ドキュメントには載っていない細かな変更点については、コミュニティで議論されている情報も重要な手がかりとなることを学びました。今後は、公式情報に加えてGitHub Issuesなどの開発者コミュニティも活用し、広く情報を収集していきます。

おわりに

今回のTailwind CSS v4へのアップデートでは、予想以上の課題に直面しましたが、多くの学びを得ることができました。特に、事前調査やスタイルの共通化、コミュニティ情報の活用が重要であることを実感しました。
これからv4への移行を検討されている方にとって、この記事が少しでもスムーズなアップデートを進める手助けとなれば嬉しいです。

参考

https://tailwindcss.com/blog/tailwindcss-v4
https://tailwindcss.com/docs/upgrade-guide

ASSIGN

Discussion