
ところが、npm run build を実行してデプロイした瞬間に、当該プロパティだけが消失する。色は灰色に、余白は標準値に、そしてテキストは黒に戻る。JavaScriptの値は正しく返っている。テンプレートの条件分岐も間違っていない。それでも本番の画面だけが崩れる。
Tailwind CSSで「動的クラスが消える」問題は、LaravelやVue、WordPressとの境界面で特に見つけにくい。APIの値、テンプレートの書き方、Tailwindのクラス抽出、そして本番用ビルドの最適化が別々の層に分かれているからだ。
この問題を単に「safelistへ追加すれば直る」と処理すると、別の画面で再発しやすい。なぜ消えるのかを理解したうえで、完全なクラス名をソースに置くのか、設定で明示的に残すのか、そもそも走査対象のパスが正しいのかを順番に確認する必要がある。個人開発で何度も同じ調査を繰り返さないために、実際の切り分けで見るべきポイントを整理する。
なぜTailwindはクラスを削除してしまうのか:静的解析の仕組み
Tailwind CSSの本番ビルドでは、プロジェクト内で使われているクラスをもとに、必要なCSSだけが生成される。使われていないユーティリティクラスをすべて出力するのではなく、Blade、Vue、JavaScript、TypeScriptなどのファイルを走査し、見つかったクラスに対応するCSSを最終成果物へ含める仕組みだ。
Tailwind CSS v2系ではPurgeCSSとの組み合わせが広く使われ、v3系以降ではTailwind独自のJITエンジンが中心になった。内部の実装や設定名は変わっているが、「ソースコードに現れているクラスを手がかりにCSSを生成する」という考え方は共通している。
ここで大切なのは、Tailwindがブラウザ上でJavaScriptを実行して、最終的なクラス名を確認しているわけではないということだ。ビルド時にソースを読み取り、クラス名らしい文字列を抽出している。実行時にAPIから返ってくる値や、関数の戻り値までは評価しない。
たとえば、次のような記述を考える。
const badgeClass = \bg-${color}-500\;
実行時に color が green なら、ブラウザ上では bg-green-500 になる。しかし、Tailwindがビルド時に見ているソースには、完全な bg-green-500 という文字列が存在しない。あるのは bg-、変数の color、そして -500 という断片だけである。
Tailwindから見れば、この時点で「どの色が必要なのか」を確定できない。green だけなのか、red、yellow、blueも返ってくる可能性があるのか、ソースの静的解析だけでは判断できないからだ。そのため、動的に組み立てられる候補を推測してCSSを生成するのではなく、検出できなかったクラスを出力対象から外す。
Tailwindのドキュメントでも、クラス名を完全な文字列として検出できる形で記述することが推奨されている。概念的には、HTMLやテンプレートの中からクラス名らしい文字列を拾う処理であり、アプリケーションのコードを実行して値を展開する処理ではない。
開発環境では動くのに、本番で壊れる理由
開発サーバーでは、変更を素早く反映するためにビルドの扱いが本番と異なる。開発時に見えていたクラスが、実際の本番用CSSに含まれているとは限らない。
特に、次のような組み合わせでは症状が見えにくい。
- 開発中は既存のCSS成果物がブラウザに残っている
- Viteの開発サーバーが変更を即時反映している
- 開発用の出力では未使用クラスの削除が本番ほど厳密ではない
- ブラウザキャッシュやサービスワーカーが古いCSSを保持している
- 画面を開く順番によって、別のコンポーネント由来のクラスが偶然出力されている
その結果、開発環境では「APIの値を変えても色が変わる」ように見える。しかし本番ビルドでは、ソースから検出できたクラスだけに絞られる。bg-${color}-500 のような書き方をしていると、実行時に生成される bg-green-500 はCSSの中に存在せず、ブラウザがクラス名を受け取っても見た目は変わらない。
この場合、Laravel APIのレスポンスを疑う前に、生成済みCSSへ対象クラスが存在するかを確認するのが早い。ブラウザの開発者ツールで要素にクラスが付いていることを確認し、それでもスタイルが当たらないなら、次にCSSファイル内を検索する。要素側に bg-green-500 があるのに、CSS側に同じセレクターがなければ、問題は実行時の値ではなくビルド時の抽出にある。
動的クラスが消えるのは、Tailwindが実行時の値を評価しない静的解析器だからだ。文字列リテラルとして完全なクラス名が存在しない限り、ビルド時に検出できず、最終CSSから外れる。
文字列結合を避ける:完全なクラス名を定義する
最初に検討する対策は、safelistを追加することではない。クラス名の組み立て方を変え、ソースコードの中に完全なクラス名を置くことだ。
ステータスや権限、表示種別のように値の候補が決まっているなら、クラス名のマッピングを用意する。APIから返ってきた値をそのままクラス名の一部に使うのではなく、許可されたキーをもとに、あらかじめ定義したクラスを参照する。
たとえば、ステータスの候補が active、inactive、pending に限定されるなら、Vue側では次のような考え方にする。
const statusClass = { active: 'bg-green-500 text-white', inactive: 'bg-red-500 text-white', pending: 'bg-yellow-500 text-black' };
テンプレートでは、APIの値をキーとして statusClass[item.status] を参照する。重要なのは、オブジェクトの値に bg-green-500、bg-red-500、bg-yellow-500 という完全なクラス名が書かれていることだ。
Tailwindがそのファイルをcontentの対象として走査できれば、実際にどの値が返るかに関係なく、これらのクラスは検出される。実行時の文字列結合に依存しないため、ビルドの結果も読みやすい。
| 実装方法 | ソース上の見え方 | Tailwindの検出 | 本番での扱い |
|---|---|---|---|
bg-${color}-500 | クラス名が断片化している | 実際の候補を確定できない | クラスが欠落しやすい |
| 条件分岐で完全名を記述 | bg-green-500などが直接現れる | 完全なクラス名を検出できる | 必要なクラスだけ生成される |
| マッピングオブジェクト | 値に完全なクラス名を列挙する | 列挙したクラスを検出できる | 許可した候補を保持できる |
safelistで登録 | ソースに現れなくても設定に存在する | 設定をもとに生成する | 指定範囲が強制的に残る |
この方式は、単にTailwind対策として優れているだけではない。APIから来た値をそのままHTMLやCSSへ流し込まないため、表示上の予期しない値にも強くなる。
たとえば、管理画面から status に未知の文字列が登録された場合、文字列結合方式では想定外のクラス名を生成する可能性がある。一方でマッピング方式なら、キーが存在しない場合のフォールバックを用意できる。
const badgeClass = statusClass[item.status] ?? 'bg-gray-500 text-white';
このフォールバックによって、APIの仕様変更やデータ移行中の不整合が起きても、画面全体のスタイルが崩れにくい。Laravel側でEnumやバリデーションを使い、フロントエンド側でも表示可能なキーを限定しておけば、バックエンドとフロントエンドの責務も明確になる。
マッピング方式で注意すること
マッピングを導入すると、値の追加が少しだけ面倒になる。Laravel側で新しいステータスを追加したのに、Vue側のマッピングを更新しなければ、未知の値としてフォールバックへ流れる。
しかし、この面倒さは欠点というより、変更箇所を明示する仕組みと考えたほうがよい。APIの値域が変わるのに、表示側が何も変えずに済む設計は、別の場所で不具合を隠していることが多い。
マッピングを保守するときは、次の対応関係を意識する。
- LaravelのEnumやバリデーションで許可する値
- APIレスポンスに含める値
- VueやReact側のマッピングキー
- 各キーに割り当てる完全なTailwindクラス
- 未知の値が来た場合の表示
カラーだけをAPIから返し、フロントエンドで bg-${color}-500 に変換する設計は、見た目の責務が複数の層へ分散する。APIから active のような意味を返し、色や余白、文字色はフロントエンドのマッピングで決めるほうが、デザイン変更にも対応しやすい。
条件分岐を使う場合も、完全なクラス名を残す
マッピングオブジェクトが大げさに見える小さなコンポーネントなら、条件分岐で書いてもよい。ただし、条件分岐の中に完全なクラス名を置くことが重要だ。
たとえば、active のときだけ bg-green-500、それ以外は bg-gray-500 とするなら、クラス名が文字列としてソースに存在する。
item.status === 'active' ? 'bg-green-500' : 'bg-gray-500'
クラス名を分割して、'bg-' + color + '-500' のように書くのは避ける。文字列の組み立て方としては自然でも、Tailwindの抽出器にとっては候補が不明なままだ。
同じ理由で、次のような書き方も注意が必要になる。
bg-${theme}-500text-${size}-lggrid-cols-${columns}md:${condition ? 'block' : 'hidden'}hover:bg-${color}-600
クラスの一部だけを変数にする設計は、色だけでなく、ブレークポイント、疑似クラス、グリッドの列数、余白、フォントサイズでも同じ問題を起こす。
動的に切り替えたい単位が複数ある場合は、完成したクラスの組み合わせをマッピングするほうが安全だ。たとえばボタンの種類に応じて背景色、文字色、ホバー状態を変えるなら、色だけを個別に組み立てるのではなく、bg-blue-600 text-white hover:bg-blue-700 のように一式を値として持たせる。
この方法なら、色の組み合わせを誤る可能性も減る。背景だけ切り替わって文字色が残る、ホバー時のクラスだけ生成されない、といった部分的な崩れを避けられる。
tailwind.config.js のsafelistを活用する
完全なクラス名をソースに書けないケースでは、tailwind.config.js の safelist が現実的な選択肢になる。
代表的なのは、必要なクラスを文字列で列挙する方法だ。
safelist: ['bg-green-500', 'bg-red-500', 'bg-yellow-500']
この方法では、対象クラスがVueテンプレートやBladeファイルに直接現れなくても、Tailwindに対して「このクラスは必ず生成する」と明示できる。CMSのデータ、WordPressの管理画面、データベースに保存された設定値など、ビルド時にソースとして存在しない情報をもとに表示を切り替える場合に向いている。
ただし、safelistは動的クラスを自由に生成する仕組みではない。登録したクラスを残すための仕組みであり、データベースから返ってくる任意の値を安全にCSSへ変換してくれるものではない。
たとえば、WordPress側のカスタムフィールドからカラー名を取得している場合、管理画面に入力された値をそのままクラス名へ変換するのは避けたい。許可する値をアプリケーション側で限定し、その候補だけをsafelistへ登録する必要がある。
完全なクラス名を配列で登録する
候補数が少ないなら、正規表現より配列指定を優先したい。登録されるクラスが目で確認でき、不要な派生クラスを増やしにくいからだ。
たとえば、ステータスバッジの色だけを残すなら、背景色、文字色、ホバー状態を必要な分だけ列挙する。
bg-green-500bg-red-500bg-yellow-500text-whitetext-blackhover:bg-green-600hover:bg-red-600hover:bg-yellow-600
クラス数が増えると配列は長くなるが、その長さ自体が「この画面で許可しているデザインの範囲」を表す。後から見た開発者が、どの値を残すための設定なのかを理解しやすい。
一方、複数の画面で同じクラス群を使う場合は、設定ファイル内でコメントや定数を使って用途を分けるとよい。色の候補、エディター用のクラス、管理画面専用のクラスを一つの巨大な配列へ混在させると、不要な登録が積み重なりやすい。
variantsの扱い
状態変化を使う場合は、元のクラスだけでなく、hover:、focus:、active:、disabled:、レスポンシブ用のバリアントなども考える必要がある。
safelist の pattern と variants を使えば、特定パターンに対する状態をまとめて指定できる。たとえば、背景色の候補に対して hover と focus も必要なら、パターンにマッチしたクラスへ状態バリアントを追加する設計にできる。
ただし、ここでも「必要な状態だけ」を指定することが大切だ。hover、focus、active、disabled、各ブレークポイントを無条件に追加すると、組み合わせが急激に増える。見た目のために登録した設定が、CSSの肥大化やビルド時間の増加につながることがある。
正規表現によるパターン指定の注意点
safelist の pattern は、色や余白などに共通した命名規則がある場合に便利だ。
たとえば、複数の色について背景色を保持したいなら、色名と強度を限定したパターンを考えられる。
/^bg-(green|red|yellow)-(500|600)$/
この指定なら、対象となる色と強度を意識的に絞り込める。反対に、/^bg-.*/ のような広すぎるパターンは避けたほうがよい。背景色に関連するクラスを広範囲に拾い、variantsやレスポンシブ指定と組み合わさった結果、想定以上のCSSを生成する可能性がある。
正規表現を使うときは、次の順番で範囲を狭める。
1. プレフィックスを限定する。背景色なのか、文字色なのか、余白なのかを分ける。
2. 値の候補を列挙する。.*で全候補を許可しない。
3. 強度やサイズを限定する。必要な値だけを残す。
4. variantsを必要な状態に絞る。
5. ビルド後のCSSサイズと生成時間を確認する。
特に注意したいのは、正規表現が「意味のある値の検証」にはならないことだ。greenやredがデザイン上許可された値かどうか、APIがその値を返してよいかどうかは、Laravelのバリデーションやアプリケーション側で管理する必要がある。
また、正規表現の対象はクラス名の一部であり、バリアントを含む完全な文字列全体ではない場合がある。hover:をパターンの中に含めるつもりで設定しても、Tailwindの設定仕様と合わなければ期待どおりに生成されない。パターンとvariantsの役割を分けて考え、実際の生成物で確認するのが確実だ。
ビルド時間とCSSサイズを確認する
safelistの登録範囲を広げたときは、画面が直ったかだけで判断しない。ビルドの所要時間と、生成されたCSSのサイズも見る必要がある。
正規表現で多くのクラスを生成すれば、ブラウザが使わないCSSまで成果物へ含まれる。CSSが大きくなれば、初回ロードやキャッシュ更新の負担が増える。個人開発の小さなサイトでは見過ごされやすいが、管理画面、会員ページ、WordPressの公開画面を一つのCSSへまとめている場合は、影響が積み上がる。
確認方法は難しくない。ビルド前後でCSSファイルのサイズを比べ、対象クラスが増えた理由を説明できる状態にしておく。Linux環境なら du -h public/build/assets/*.css のように出力サイズを確認できるし、生成されたCSSへ grepでクラスの存在を調べることもできる。
数値を監視する場合も、絶対値だけで合否を決めるより、前回ビルドとの差分を見るほうが運用しやすい。色を一つ追加しただけなのにCSSが大きく膨らんでいるなら、パターンの指定範囲かvariantsの展開を疑うべきだ。
content設定の見直し:クラス抽出漏れを防ぐ
safelistを設定してもクラスが生成されない、あるいは一部の画面だけスタイルが欠ける場合は、contentの指定を確認する。
Tailwind CSS v3系では、通常 tailwind.config.js の content に、クラスを記述しているファイルのパスを指定する。Laravel、Vue、React、Blade、TypeScriptなどを組み合わせているなら、それぞれのファイルが走査対象に含まれていなければならない。
たとえばLaravelとVueを同居させるプロジェクトでは、次のようなパス構成を検討する。
resources/**/*.blade.phpresources/**/*.vueresources/**/*.jsresources/**/*.ts
実際のディレクトリ構成に合わせる必要があるため、どこにファイルがあるかを先に確認する。resources/js/componentsだけを指定して、resources/js/pagesや別のサブディレクトリを外していると、その場所に書いたクラスだけが検出されない。
WordPressを扱う場合も同じだ。テーマ内のPHPテンプレート、ブロック用のJavaScript、ビルド前のソースがどこに置かれているのかを整理し、必要なファイルをcontentへ含める。ただし、WordPressの管理画面でデータベースから生成されるHTMLや、管理画面の入力値そのものは、Tailwindのビルド時に存在しない。contentへパスを足すだけでは解決できず、そうした値はsafelistやマッピングで補う必要がある。
パスを追加するだけでは直らないケース
content設定の漏れと、動的クラスの問題は似ているが、原因は異なる。
Vueファイルの中に bg-green-500 と完全なクラス名が書かれているのに、出力CSSへ存在しないなら、まずcontentのパスを疑う。一方、Vueファイルが正しく走査されていても、そこに bg-${color}-500 しか書かれていないなら、パスを追加しても完全なクラス名は検出できない。
切り分けるときは、次のように単純化したテストを行う。
1. 対象コンポーネントに完全なクラス名を一時的に直接記述する。
2. npm run buildを実行する。
3. 生成CSSへそのクラスが含まれるか確認する。
4. 含まれるなら、contentのパスはおおむね正しく、動的生成方法に問題があると判断する。
5. 含まれないなら、content、設定ファイルの読み込み、ビルド対象のCSSを確認する。
一時的な直接記述で直るからといって、そのまま見えない場所へクラスを置いて解決するのは避けたい。たとえば、テンプレートのコメントへクラスを列挙する方法は動くことがあるが、なぜそのクラスが必要なのかが分かりにくく、後から削除されやすい。マッピングかsafelistか、用途に合った場所へ移したほうが保守しやすい。
拡張子とビルド対象も確認する
contentのglobが正しくても、実際にビルドで読み込まれているTailwind設定が別ファイルなら、修正が反映されないことがある。
LaravelとViteの構成を変更した後に、Tailwind設定だけ古いディレクトリを参照しているケースもある。複数のフロントエンドを持つプロジェクトでは、管理画面用と公開画面用でCSSのエントリーポイントが分かれていることもある。
確認する場所は次のとおりだ。
- 実際に読み込まれているTailwind設定ファイル
- ViteがビルドしているCSSのエントリーポイント
contentに指定した拡張子- コンポーネントの実ファイル名と配置場所
- 本番で参照されているCSSファイル
- ブラウザキャッシュではなく、最新ビルドの成果物を見ているか
設定を変更したのに結果が変わらない場合、設定内容よりも「その設定が使われているか」を疑う。個人開発では、試行錯誤の途中で設定ファイルやビルド構成が増え、古いファイルを編集していたということが珍しくない。
Laravel APIとの境界で起きる設計上の問題
Laravel APIからCSSクラス名そのものを返す設計は、短期的には便利に見える。レスポンスに buttonClass や badgeClass を含め、フロントエンドはそのまま :classへ渡すだけで済むからだ。
しかし、APIレスポンスの値はビルド時に存在しない。Tailwindが走査できるのは、APIを呼び出すコードやテンプレートであって、データベースから後で返ってくる文字列ではない。
たとえば、Laravelが次のような値を返すとする。
{ "buttonClass": "bg-blue-600 text-white hover:bg-blue-700" }
この文字列がVueファイル内に直接書かれていなければ、content設定が正しくてもTailwindは検出できない。APIが返す値の候補をsafelistへ登録するか、APIは primary や danger のような意味を返し、フロントエンド側でクラスへマッピングする必要がある。
後者のほうが、アプリケーション全体の責務を整理しやすい。Laravelは状態や権限といったドメイン上の意味を返し、フロントエンドはそれを表示ルールへ変換する。WordPressのカスタムフィールドを使う場合も、入力された値をそのままクラスにせず、許可したキーへ変換してから表示する。
API側で最低限行いたいのは、値域の制限だ。
- ステータス値をEnumやバリデーションで限定する
- 未知の値を返す場合の扱いを決める
- CSSクラス名ではなく、意味を表す識別子を優先する
- フロントエンド側にフォールバックを用意する
- 新しい値を追加したときのマッピング更新箇所を明確にする
Tailwindのビルド問題に見えて、実際にはAPI契約の曖昧さが原因になっていることもある。クラス名をどの層が所有するのかを決めないまま開発を進めると、Laravel、Vue、WordPressの各所に似た変換ロジックが増えていく。
本番ビルドでの検証手順
修正後は、開発サーバーで表示を確認するだけでは不十分だ。今回の問題は本番ビルドで初めて発生するため、同じコマンドと同じ成果物を対象に検証する。
まずブラウザの開発者ツールで、対象要素に期待するクラスが付いているかを見る。クラスが付いていないなら、APIレスポンス、条件分岐、コンポーネントのバインディングを確認する。クラスが付いているのに表示されないなら、生成CSSに対応するセレクターがあるかを調べる。
生成CSSを検索する場合は、たとえば grep -c "bg-green-500" public/build/assets/*.css のように、対象クラスの有無を確認できる。CSSが圧縮されていても、クラス名が存在するかどうかの調査には使える。
確認の順序を固定すると、調査が早くなる。
1. APIレスポンスに想定した値が入っているか確認する。
2. VueやBladeの要素に期待する完全なクラス名が付いているか確認する。
3. 生成済みCSSにそのクラスのセレクターがあるか検索する。
4. クラスがなければ、完全な文字列の記述、safelist、content設定を確認する。
5. クラスがあれば、CSSの優先順位、別クラスによる上書き、ビルド成果物の参照先を確認する。
6. 本番サーバーやCDNのキャッシュを削除し、最新ファイルを参照しているか確認する。
この手順を踏まずに、いきなりsafelistへ候補を追加するのは危険だ。問題がcontentのパス漏れなら、safelistに登録したクラスだけ直って、別のクラスは引き続き消える。問題がCSSの上書きなら、クラスを残しても見た目は変わらない。
CIでの再発防止
毎回手作業で本番CSSを検索するのが難しければ、重要なクラスの存在確認をCIに組み込む方法もある。ビルド後のCSSに、主要画面で必須となるクラスが含まれているかを確認するだけでも、デプロイ後に初めて気付く事故を減らせる。
ただし、すべてのクラスを固定的に検査すると、デザイン変更のたびにテストが壊れる。検査対象は、ログイン状態、エラー表示、権限によるボタンの切り替えなど、本番で見えにくいが欠けると困る状態に絞るのがよい。
CSSのサイズ監視も有効だ。safelistの変更やTailwindの設定変更によって成果物が急増した場合、ビルド自体は成功していても、設計上の問題が入り込んでいる可能性がある。
対策の優先順位とトレードオフ
Tailwind CSSの動的クラスが消える問題は、静的解析の仕様と、実装側の文字列の置き方が噛み合っていないことで起きる。対策は一つではないが、適用する順番はある。
まず、値の候補が決まっているなら、完全なクラス名をマッピングとしてソースに記述する。これは最も分かりやすく、生成されるCSSも必要な範囲に収まりやすい。
次に、contentのパスを見直す。完全なクラス名を記述しているのに検出されない場合、safelistを追加する前に、ファイルが走査対象へ入っているかを確認する。
それでもソース上にクラスを置けない場合に、safelistを使う。候補が少なければ文字列配列で列挙し、共通した規則があり、数が多い場合だけpatternを検討する。
正規表現のsafelistは最後に使う。広いパターンで一度直してしまうと、どのクラスが必要で、どのクラスが不要なのかが見えなくなる。後からCSSを削ろうとしても、設定のどこが出力を膨らませているのか分かりにくくなるからだ。
整理すると、各方式の特徴は次のとおりである。
- 完全なクラス名のマッピング
実装の意図が明確で、CSSの生成範囲も制御しやすい。APIの値域が変わったときに、マッピングの更新が必要になる。
- safelistの完全列挙
設定だけで明示的にクラスを保持できる。登録漏れは起きるが、どのクラスを残すかを確認しやすい。
- safelistのpattern指定
候補が多い場合に便利。ただし、パターンが広すぎるとCSSサイズやビルド時間が増える。
- content設定の見直し
完全なクラス名があるのに検出されない場合の基本対策。副作用は少ないが、実際のビルド構成とパスを正しく把握する必要がある。
safelistは動的クラスの万能修理パッチではない。値域が決まっているならマッピング、ソースが走査されていないならcontent設定を先に直すべきである。まとめ:npm run devではなく、生成物を見る
Tailwind CSSで動的クラスが消えるトラブルは、開発環境と本番環境の違いが作る錯覚から始まる。画面上でクラスが生成されているからといって、本番CSSにそのクラスが含まれているとは限らない。
調査では、まず要素にクラスが付いているか、次に生成CSSにセレクターがあるかを分けて見る。この二つを混同しなければ、Laravel APIの値の問題なのか、Vueテンプレートの書き方なのか、Tailwindの抽出設定なのかを切り分けられる。
値の候補が決まっているなら、bg-${color}-500 のような文字列結合をやめ、完全なクラス名をマッピングする。APIやWordPressからビルド後に渡ってくる値なら、許可する候補を整理したうえでsafelistへ登録する。候補が少ない場合は完全列挙を優先し、patternを使う場合は対象とvariantsを狭く保つ。
そして、Laravel、Vue、WordPressのファイルが実際にcontentの走査対象へ入っているかを確認する。設定を直した後は、npm run buildで生成したCSSを検索し、必要なクラスが残っていることを検証する。
Tailwindは、実行時にどんな値が来るかを推測してくれる仕組みではない。ビルド時に見える情報だけを材料にCSSを作る。その前提に合わせてクラス名の管理場所とAPIの責務を整理すれば、本番だけ色が消える、余白だけ戻る、といった不可解な不具合はかなり減らせる。
個人開発では、開発サーバーで動いたことよりも、デプロイする成果物に必要なクラスが入っていることのほうが重要だ。Tailwindの設定を増やす前に、完全なクラス名がどこにあり、どのファイルをビルドが読んでいるのかを確認する。その地味な確認が、再発防止への一番短い道になる。