本地构建一切正常,但一到 Vercel 就报错?这可能是 Git 大小写敏感性在作祟。本文将分享一个真实的故障排查案例,帮助你避免这个隐蔽的跨平台兼容性问题。
问题背景:诡异的构建失败
最近在部署一个 React 项目到 Vercel 时,遇到了一个令人困惑的问题:
pnpm run build
22:32:28.979 src/api/Article.ts(27,43): error TS2307:
Cannot find module './HttpClient' or its corresponding type declarations.
奇怪的是,相同的代码、相同的依赖、相同的构建命令,在本地能够完美构建,但在 Vercel 上却失败了。
问题根源:大小写敏感性的差异
经过排查,发现问题出在文件命名上:
- 实际文件名:
httpClient.ts(首字母小写) - 导入语句:
import HttpClient from './HttpClient';(首字母大写)
这个差异在不同操作系统环境下表现不同:
操作系统差异
| 环境 |
大小写敏感性 |
行为 |
| Windows |
不敏感 |
./HttpClient 和 ./httpClient 都能找到文件 |
| macOS |
通常不敏感 |
同上 |
| Linux (Vercel) |
敏感 |
必须精确匹配 ./HttpClient |
Git 的配置陷阱
问题的深层原因在于 Git 的配置:
git config core.ignorecase
当 core.ignorecase=true 时,Git 不会区分文件名的大小写,这就导致了:
- 在 Windows/Mac 上开发时,一切正常
- 文件被提交为
httpClient.ts(小写) - 但在 Linux 构建环境中,导入语句找不到对应的文件
解决方案:三步修复法
第一步:诊断问题
find . -name "*httpclient*" -type f
git ls-files | grep -i httpclient
第二步:修复文件名
git config core.ignorecase false
git mv src/api/httpClient.ts src/api/HttpClient.temp.ts
git mv src/api/HttpClient.temp.ts src/api/HttpClient.ts
git commit -m "fix: correct HttpClient filename case sensitivity"
git push origin feat/reactpresss-config-v2
第三步:验证修复
预防措施:建立防护网
1. 项目级配置
在项目中添加 .gitconfig 文件:
[core]
ignorecase = false
2. ESLint 规则检查
配置 ESLint 检查文件名规范:
module.exports = {
rules: {
'unicorn/filename-case': [
'error',
{
cases: {
camelCase: true,
pascalCase: true
}
}
]
}
};
3. CI/CD 流水线检查
在 GitHub Actions 中添加检查:
name: Check Filename Case
on: [push, pull_request]
jobs:
check-case:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Check filename consistency
run: |
for file in $(find src -name "*.ts" -o -name "*.tsx"); do
filename=$(basename "$file" .ts | basename "$file" .tsx)
if [[ $filename =~ [A-Z] ]]; then
echo "✓ $filename uses PascalCase"
else
echo "⚠ $filename - consider using PascalCase for components/classes"
fi
done
4. 预提交钩子
使用 Husky 在提交前检查:
#!/bin/bash
find src -name "*.ts" -o -name "*.tsx" | while read file; do
base=$(basename "$file")
if [[ $base =~ ^[a-z] ]] && [[ $base =~ \.(ts|tsx)$ ]]; then
echo "警告: 建议类文件使用 PascalCase: $file"
fi
done
深入理解:为什么会有这种差异?
历史原因
- Windows: 源于 DOS,设计初衷是用户友好,不区分大小写
- Linux: 源于 UNIX,强调精确和一致性,区分大小写
- macOS: 基于 UNIX,但默认文件系统 HFS+/APFS 通常不区分大小写
Git 的设计选择
Git 为了跨平台兼容性,默认采用 core.ignorecase=true,这在实际开发中带来了便利,但也埋下了隐患。
最佳实践总结
- 统一命名规范
- 类文件使用 PascalCase:
HttpClient.ts - 工具函数使用 camelCase:
formatDate.ts - 配置文件使用 kebab-case:
app-config.ts
- 团队协作约定
- 新成员入职时强调文件名规范
- 代码审查时注意文件名大小写
- 使用工具自动化检查
- 跨平台开发策略
- 主要开发环境尽量与生产环境一致(推荐使用 Linux 容器)
- 定期在 CI/CD 环境中测试构建
- 建立快速反馈机制
结语
这个看似简单的"大小写"问题,实际上涉及操作系统设计、Git 工作原理、团队协作规范等多个层面。在跨平台开发日益普遍的今天,我们需要更加重视这类环境差异导致的问题。
记住:在本地能运行只是第一步,在生产环境能运行才是真正的完成。
希望通过这个案例,你能避免类似的陷阱,建立更健壮的开发工作流。