本地构建正常,Vercel等平台部署时usePlatforms钩子导入失败求助
Vercel部署构建失败:模块导入找不到问题(本地构建正常)
问题现象
本地执行构建命令完全成功,但部署到Vercel或其他主机时,TypeScript抛出模块找不到的错误:
[12:07:15.658] src/Components/PlatformSelector/PlatformSelector.tsx(5,26): error TS2307: Cannot find module '../../Hooks/usePlatforms' or its corresponding type declarations. [12:07:15.659] src/Hooks/usePlatform.ts(1,26): error TS2307: Cannot find module './usePlatforms' or its corresponding type declarations. [12:07:15.694] Error: Command "npm run build" exited with 2
相关代码
usePlatform.ts
import Platform from "../Entities/Platform"; import usePlatforms from "./usePlatforms"; const usePlatform = (id?: number) => { const {data: platforms} = usePlatforms(); return platforms?.results.find((p: Platform) => p.id === id) } export default usePlatform;
usePlatforms.ts
import { useQuery } from '@tanstack/react-query'; import ms from 'ms'; import platforms from '../data/platforms'; import Platform from '../entities/Platform'; import APIClient from '../services/api-client'; const apiClient = new APIClient<Platform>( '/platforms/lists/parents' ); const usePlatforms = () => useQuery({ queryKey: ['platforms'], queryFn: apiClient.getAll, staleTime: ms('24h'), initialData: platforms, }); export default usePlatforms;
PlatformSelector.tsx
import { Button, Menu, MenuButton, MenuItem, MenuList } from "@chakra-ui/react"; import { BsChevronDown } from "react-icons/bs"; import Platform from "../../Entities/Platform"; import usePlatform from "../../Hooks/usePlatform"; import usePlatforms from "../../Hooks/usePlatforms"; import useGameQueryStore from "../../store"; const PlatformSelector = () => { const setPlatformId = useGameQueryStore((state) => state.setPlatformId); const selectedPlatformId = useGameQueryStore( (state) => state.gameQuery.platformId ); const selectedPlatform = usePlatform(selectedPlatformId); const { data, error } = usePlatforms(); if (error) return null; return ( <Menu> <MenuButton as={Button} rightIcon={<BsChevronDown />}> {selectedPlatform?.name || "Platforms"} </MenuButton> <MenuList> {data?.results.map((platform: Platform) => ( <MenuItem onClick={() => setPlatformId(platform.id)} key={platform.id} > {platform.name} </MenuItem> ))} </MenuList> </Menu> ); }; export default PlatformSelector;
已尝试的解决方法
- 修改了
usePlatforms钩子的文件名大小写(原首字母大写) - 在
tsconfig.json中设置"forceConsistentCasingInFileNames": false
解决方案
1. 彻底对齐文件名与导入路径的大小写
部署环境(如Linux服务器)是大小写敏感的,而本地Windows/macOS默认不区分。即使关闭了forceConsistentCasingInFileNames,仍需确保:
- 实际文件名(如
src/Hooks/usePlatforms.ts)与导入语句中的路径(./usePlatforms/../../Hooks/usePlatforms)大小写完全一致 - 检查是否存在拼写错误,比如把
usePlatforms写成usePlatform或其他变体
2. 修正Git仓库中的文件名大小写
如果本地修改了文件名大小写,但Git未识别(系统不区分大小写导致),远程仓库仍保留旧文件名:
# 强制重命名文件并提交到Git git mv src/Hooks/UsePlatforms.ts src/Hooks/usePlatforms.ts git commit -m "fix: correct filename casing for usePlatforms" git push
之后重新触发Vercel部署。
3. 清理Vercel部署缓存
Vercel的缓存可能残留旧的文件信息:
- 进入Vercel控制台对应项目的部署页面
- 点击"Redeploy",勾选"Skip Cache"选项后重新部署
4. 检查相对路径层级是否正确
确认导入路径的层级无误:
PlatformSelector.tsx位于src/Components/PlatformSelector/,../../Hooks/usePlatforms指向src/Hooks/usePlatforms.ts,确认该文件存在且路径正确usePlatform.ts位于src/Hooks/,./usePlatforms指向同目录下的usePlatforms.ts,确认文件存在
5. 尝试显式指定文件扩展名
在导入语句中添加.ts扩展名,避免TypeScript路径解析异常:
// usePlatform.ts中修改导入 import usePlatforms from "./usePlatforms.ts"; // PlatformSelector.tsx中修改导入 import usePlatforms from "../../Hooks/usePlatforms.ts";
内容的提问来源于stack exchange,提问作者ivsheva
相关产品推荐
相关产品推荐

