Vercel build failed 常见原因

Vercel build 挂掉几乎都是 6 类原因之一。按日志匹配类别,直接粘贴对应修复。

本地 npm run build 绿。Vercel 显示 “Build failed”。郁闷,但失败模式有限。6 个类别覆盖 95% 的真实失败,知道在哪看 build 日志就能定位到哪一类。下面给出每类的日志关键词、诊断命令和配置修复。

问题背景

Vercel 在干净的 Linux 容器里跑 build,用你指定的 Node 版本(默认 20 LTS)。和本地差异——Node 版本、环境变量、路径大小写敏感、npm 源——都是常见元凶。Build log 里最后失败的那步基本就是真实原因。

判断标准

日志字符串                             → 类别
"Cannot find module"                  → 依赖或路径大小写
"process is not defined"              → Production 缺环境变量
"Type error"                          → TypeScript 比本地严
"Killed"(无其它信息)                  → 内存不足(OOM)
build 跑超 45 分钟后挂                 → 超时
"Module not found: Error: Can't ..."  → 依赖或 alias
昨天能 build 今天挂                    → 缓存陈旧或依赖飘了

快速结论

先读 build log 里失败那步,再对到上面的分类,跳到对应修复方案。

开始前准备

  • 打开失败 deployment 页,复制失败日志行。
  • package.jsonvercel.json 摆在眼前。
  • 知道本地 Node 版本(node -v)。

实操步骤

  1. 读失败那步。 Build Logs → 搜 “error” 或滚到最底部红色块。失败退出前一行通常就是真因。

  2. Pin Node 版本。 package.json

{
  "engines": { "node": "20.x" },
  "scripts": { "build": "astro build" }
}

commit 后重新部署,Vercel 严格按 engines.node 跑。

  1. 补缺的环境变量。 Vercel Dashboard → Project → Settings → Environment Variables → 加 Production(也可加 Preview)。然后重新部署。Vercel CLI:
vercel env add OPENAI_API_KEY production
# 按提示粘贴 secret
vercel env add SITE_URL production
# https://yourdomain.com
vercel --prod              # 触发干净部署
  1. 类型错误本地先复现:
npx tsc --noEmit
# tsconfig.json 有 "strict": true 时与 Vercel 一致

要么改代码,要么 strictness 是误开就放松:

{
  "compilerOptions": {
    "strict": true,
    "skipLibCheck": true,
    "noUncheckedIndexedAccess": false
  }
}
  1. 依赖 / 路径错位。 lockfile 飘是经典:
rm -rf node_modules package-lock.json
npm install
git add package-lock.json
git commit -m "fix: refresh lockfile"

Vercel 里 Deployments → Redeploy → 取消 “Use existing build cache” 强制干净安装。日志也留意路径大小写——./Components/Foo vs ./components/Foo 在 macOS 行、Vercel Linux 挂。

  1. OOM(“Killed”)。 降低 build 内存使用,Astro:
// astro.config.mjs
export default defineConfig({
  build: {
    concurrency: 1,                   // 串行生成页面
    inlineStylesheets: 'never',
  },
  image: { service: { entrypoint: 'astro/assets/services/sharp' } },
});

Next.js:临时加 Node 堆(package.json):

{
  "scripts": {
    "build": "NODE_OPTIONS='--max-old-space-size=4096' next build"
  }
}

Vercel Pro 内存上限更高;Hobby 限制更紧。

  1. 超时。 Hobby 45 分钟硬上限。内容站撞顶就拆 build(按语言或按板块),或者升 Pro。常用技巧:
// astro.config.mjs —— 每次 build 限制静态页面数
export default defineConfig({
  build: { format: 'directory' },
  // 单次只生成最近 N 篇;老的走单独部署
});
  1. 同一个改动先在本地能 build。 本地可重现失败能极大缩短迭代时间:
npm ci          # 按 lockfile 干净安装
npm run build   # 完全匹配 Vercel 的 build 命令

执行检查清单

  • package.json 设了 engines.node
  • Production 和任何其它会 build 的环境都有所需变量。
  • tsc --noEmit 本地通过。
  • lockfile 已 commit 且最新。
  • 改完 env / 配置后第一次重新部署用 “no cache”。

上线后验证

  • 修完后下一次部署绿色完成。
  • build log 里不再有之前的错误字符串。
  • build 时间在套餐上限内。

容易踩的坑

  • 只看 build log 最下面——真实错误往往在中间。
  • 环境变量只加 Preview 没加 Production(或反过来)然后纳闷。
  • node_modules 提交到仓库去”修”依赖错——仓库变大、build 更慢。
  • 为绕一个类型错全局关 TypeScript 严格模式——问题往后推。
  • 为”先上线”改 build 命令跳过 lint / 测试——失败会以运行时崩溃形式再来。

FAQ

  • 怎么找到真正的错误信息?: deployment 页打开 Build Logs,搜 “error”。第一个匹配通常就是原因。
  • 本地能 build Vercel 挂,怎么办?: Node 版本不同、缺环境变量、路径大小写敏感,或你本地有的 peer 依赖但 lockfile 里没。
  • 不改代码能重跑 build 吗?: 能。Deployments → 选失败那次 → “Redeploy”,可以勾掉 “use existing build cache”。
  • “Killed” 是什么意思?: OOM。减小 bundle、减少图片集、减少同时生成的页面,或升级拿更多内存。
  • 能本地跑 Vercel 的 build 容器吗?: 近似可以,Vercel CLI:vercel build --prodvercel deploy --prebuilt --prod,环境很接近。

相关阅读

标签: #独立开发 #Vercel #部署 / 托管 #排查