Vercel build failed 怎么修:7 类原因和精确修复

Vercel "Build failed" 几乎都是 7 类原因之一:Node 版本、缺环境变量、类型错误、依赖漂移、内存不足、输出目录错、超时。按日志匹配,直接粘贴修复。

本地 npm run build 是绿的,Vercel 却显示 Build failed。烦人,但失败模式就那么几种:7 个类别覆盖约 95% 的真实失败,build 日志会告诉你是哪一类——前提是你知道往哪看。本文给出每一类的精确日志字符串、一条诊断命令、一处配置修复。文中数字以 2026 年 6 月为准。

TL;DR

  • 打开失败的 deployment,点 Building,滚到进程退出前最后一行红色。那行约 90% 的情况就是真因。
  • build 跑在干净的 Linux 容器里,默认 Node 24.x(可固定到 20.x 或 22.x)。你的 Mac 跑的是另一个 Node 版本、有你的环境变量、且文件路径大小写不敏感。绝大多数失败就出在这三个差异上。
  • 每个 build 容器有 8192 MB(8 GB)内存,并且每个套餐(包括 Pro)都是 45 分钟硬超时——这两个上限不会因为单纯升级席位而提高。

怎么读那行日志

把失败行对到一个类别,再跳到下面对应的修复。

日志字符串                                      → 类别
"Cannot find module" / "Module not found"      → 依赖漂移或路径大小写
"process is not defined" / 环境变量为 undefined  → build 阶段缺环境变量
"Type error:" / "tsc" 非零退出                  → TypeScript 比本地严
"Killed" / "SIGKILL" / "heap out of memory"    → 内存不足(OOM)
"No Output Directory named ... found"          → 框架预设 / 输出目录错
"Command failed with exit code 1"              → 笼统报错:读它上面那行
build 跑约 45 分钟后停                          → 超时(Hobby 和 Pro 一样)
"昨天能 build 今天挂,代码没动"                  → 缓存陈旧或依赖漂移

7 类原因和对应修复

1. Node 版本不一致

Vercel 新项目默认 Node 24.x(截至 2026 年 6 月,可用主版本是 24.x、22.x、20.x)。如果你的代码依赖本地 Node 有、而 24.x 砍掉的东西,或者你在 20 上开发、某个依赖却需要 22+,build 就和本地分叉了。直接在 package.json 里固定版本,免得 dashboard 设置悄悄变动:

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

Vercel 读 engines.node,部署该主版本的最新补丁版。Project Settings 下拉框(Settings → Build and Deployment → Node.js Version)是没写 engines 时的兜底。两者选其一,别同时较劲。

2. 缺环境变量

典型症状是 process is not defined,或某个值在 build 阶段(而非运行时)读出来是 undefined。Vercel 不会拷贝你本地的 .env——变量存在 dashboard 里,按环境分别配置。只加到 Preview 没加到 Production 的变量,只在生产部署时失败,这正是”我 PR 上能 build、合到 main 就挂”的常见原因。

vercel env add OPENAI_API_KEY production
# 按提示粘贴 secret
vercel env add SITE_URL production
# https://yourdomain.com
vercel --prod              # 触发一次干净部署

Dashboard 路径:Settings → Environment Variables,给每一个会跑 build 的环境都加上变量。Next.js 里浏览器要读的变量必须以 NEXT_PUBLIC_ 开头、且在 build 时就存在——缺一个 NEXT_PUBLIC_*exit code 1 的高频成因。

3. Vercel 上 TypeScript 比本地严

你看到 Type error:tsc 非零退出。通常是编辑器默默放过了什么,或本地 skipLibCheck 把问题盖住了。先在本地复现 Vercel 实际跑的命令:

npx tsc --noEmit
# tsconfig.json 里 "strict": true 时,这会暴露 Vercel 看到的同样错误

先改代码。只有确认 strictness 是误开时才放松配置——而且要精准放松,不要直接关掉整个 strict

{
  "compilerOptions": {
    "strict": true,
    "skipLibCheck": true,
    "noUncheckedIndexedAccess": false
  }
}

4. 依赖漂移或路径大小写 bug

本地绿、Vercel 报 Cannot find moduleModule not found,通常是提交到 git 的 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”,强制干净安装。还要留意更隐蔽的那种:macOS 路径大小写不敏感,Vercel 的 Linux 容器大小写敏感。import Foo from './Components/Foo' 在你的 Mac 上能解析,但若文件夹实际叫 components,在 Vercel 上就挂。把 import 里和真实路径大小写不符的地方 grep 出来。

5. 内存不足(“Killed” / SIGKILL)

每个 build 容器上限 8192 MB(8 GB)。build 超过这个量时,Node 会被 SIGKILL 杀掉,日志显示 KilledJavaScript heap out of memory,往往没有别的上下文。按顺序用两招:

第一招,把 Node 的堆抬到接近容器上限但留出余量。Vercel 自己建议留点空间,所以目标设 6 GB 而非 8:

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

第二招,在 build 本身里压低峰值内存。Astro 可以串行生成页面,别什么都内联:

// astro.config.mjs
export default defineConfig({
  build: {
    concurrency: 1,                 // 串行生成页面,降低峰值内存
    inlineStylesheets: 'never',
  },
  image: { service: { entrypoint: 'astro/assets/services/sharp' } },
});

如果确实需要超过 8 GB,Pro 和 Enterprise 可以开 on-demand enhanced builds(8 CPU、16 GB 内存、58 GB 磁盘)。光把席位升到 Pro 并不会让 build 内存翻倍——必须主动把 enhanced builds 打开。

6. 输出目录 / 框架预设错

build 本身”成功”,但部署时报 No Output Directory named "public" found。Vercel 期望静态文件在 public,而你的框架写在别处——Astro 和 Vite 输出 dist,Next.js 输出 .next。这通常是框架预设设错,或某个手动的 Output Directory 覆盖项过时了。

Settings → Build and Deployment 修:把 Framework Preset 设成和你的技术栈匹配(Astro、Next.js、Vite…),并清掉任何手动的 Output Directory 覆盖(除非你真需要自定义)。让预设自己决定目录。

7. build 超时(45 分钟,每个套餐都一样)

Build Step 有 45 分钟硬上限,所有套餐都一样——Hobby 和 Pro 没区别。升级席位不会抬高它。在大型内容站上,你是靠一次性生成太多页面撞顶的。几个选择:

  • 按语言或板块拆 build,作为多个独立项目部署。
  • 每次 build 只生成最近 N 篇,其余的归档到单独部署里。
  • 给 build 本身提速(更快的图片服务、减少冗余数据请求、在多次运行间复用缓存),让同样的页面数在 45 分钟内跑完。
// astro.config.mjs —— directory 输出,再限制每次 build 的页面数
export default defineConfig({
  build: { format: 'directory' },
});

push 前先在本地复现失败

可复现的本地失败能把重新部署的循环从几分钟压缩到几秒。匹配 Vercel 的精确 build 路径:

npm ci          # 严格按 lockfile 干净安装
npm run build   # 和 Vercel 跑的同一条命令

想更贴近 Vercel 自己的容器环境,用 CLI:

vercel build --prod
vercel deploy --prebuilt --prod

容易踩的坑

  • 只看 build 日志最底部。真实错误经常在最后那行 “exit code 1” 上面几行。
  • 把环境变量加到了一个环境(Preview),却没加到真正失败的那个(Production)。
  • 为”修”依赖错把 node_modules 提交进仓库。这会撑大仓库、拖慢每次 build;刷新 lockfile 才对。
  • 为绕一个类型错就全局关掉 strict。你把后面那十个错也一起藏起来了。
  • 以为 Pro 会自动抬高 45 分钟超时或 8 GB build 内存。超时在每个套餐上都固定;内存提升需要主动开 enhanced builds。

FAQ

  • 真正的错误到底在日志哪里?: 打开 deployment,展开 Building 步骤,找进程以非零码退出前最后一行红色。最底部的 “Command failed with exit code 1” 只是症状,真因通常在它上面一两行。
  • 为什么本地能 build、Vercel 挂?: 三个常见差异——Node 版本不同(Vercel 默认 24.x)、某个 build 阶段的环境变量只存在你机器上、或某个文件路径的大小写在大小写不敏感的 macOS 上行、在大小写敏感的 Vercel Linux 上不行。
  • 日志只写 “Killed” 是什么意思?: 内存不足。容器上限 8 GB。设 NODE_OPTIONS='--max-old-space-size=6144',降低并发和图片处理量,再不行才考虑 Pro 的 on-demand enhanced builds(16 GB)。
  • 升级 Pro 能解决 build 超时吗?: 不能。45 分钟 build 上限在 Hobby 和 Pro 上完全一样。拆 build 或给它提速,升席位在这里帮不上忙。
  • 能在本机跑 Vercel 的 build 容器吗?: 很接近,可以:vercel build --prodvercel deploy --prebuilt --prod,比单纯 npm run build 更贴近 Vercel 的 build 环境。

相关阅读

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