経緯
- 以下
respondentLoader.ts
というロジックファイルをrespondentLoader.tsx
としていた - ローカル環境ではうまくいくけど、github actionsでfirebaseに自動デプロイした際に、
respondentLoader
を読み込むコンポーネントにて、respondentLoaderが見つからないエラー
が発生した
respondentLoader.ts
import { LoaderFunction } from "react-router-dom";
import { fetchFlowByUrl } from "@/db/functions/flow";
import { queryClient } from "@/app/queryClient";
import { type RespondentData } from "@/db/functions/flow";
export type RespondentLoaderData = {
respondent: Promise<RespondentData>;
};
export const respondentLoader: LoaderFunction = async ({ params: { shopName, flowUrl } }) => {
const queryKey = ["flows", shopName!, flowUrl!];
await queryClient.prefetchQuery({
queryKey,
queryFn: async () => await fetchFlowByUrl(shopName!, flowUrl!),
});
const respondentData = queryClient.getQueryData(queryKey);
if (!respondentData) {
throw new Error("指定されたURLのアンケートは存在しません");
}
return {
respondent: respondentData,
};
};
原因と解決方法
respondentLoader
の拡張子を.ts→.tsxに変更すれば解決した。
TypeScriptやビルドプロセスにおける ファイル拡張子の扱いが異なるために発生した
TypeScriptとファイル拡張子の解釈の違い
.ts ファイル
- 純粋なTypeScriptファイル
- 主にロジックや型定義、ユーティリティなどを記述するために使用
- Reactコンポーネントが含まれていないファイルに適している
.tsx ファイル
- TypeScriptの拡張で、JSX記法(ReactのUI記述)を含むファイルに使用
- TypeScriptは.tsxファイルに対してJSXの構文解析を行おうとする
エラーの原因
TypeScriptがJSX解析を試みようとするのに対して、respondentLoader
ファイルは純粋なロジックと型定義のみなので、余計な解析が行われた。
Firebase Hostingのビルド環境では、.tsx ファイルが不要な解析の対象となり、正しく解決されない可能性がある。
また、respondentLoader.tsx としてファイル名を記載した場合、モジュール解決が環境によって失敗することがあります。
なぜローカルでは問題なかったのか
ローカル環境では、TypeScriptの構文解析が正しく行われ、.tsxでも問題なく解決されていた。
Firebase HostingやCI/CD環境では、より厳密な設定や異なるモジュール解決が行われ、.tsx の扱いに関する差異によって発生した可能性がある。