这应该是《Vercel暗坑》系列的第二篇。上一篇主要聊了部署静态站和前端项目时最基础的那批坑,比如构建失败、环境变量不生效、免费额度莫名其妙就超了。这一篇我想换个角度,专门讲讲大家问得最多的三个深水区:免费账号的隐形限制、绑定域名时的DNS折腾,以及Serverless函数和部署流程里那些文档里不会写明白的潜规则。内容适合两类人:刚从零开始准备用Vercel的新手,以及已经用了一段时间、但总觉得"哪里不对劲"的开发老手。我会尽量把每个坑背后的原因和解决办法都拆开讲,而不是只丢一句"这样点就行了"。
1. 内容整体设计与思路拆解
1.1 为什么Vercel这么能打,暗坑却这么多
Vercel能火起来,核心其实就三个字:省事。你把代码推到GitHub,它自动帮你构建、部署、分配HTTPS证书,还把站点分发到全球边缘节点。对独立开发者来说,这是目前把前端项目从零跑到线上成本最低的方案之一。而且它不光是静态托管,Next.js这类全栈框架在上面几乎是原生支持,Serverless函数、边缘中间件、预览部署一整套都是现成的。
但"省事"的另一面是"黑盒"。Vercel把太多东西自动化了,自动识别框架、自动配置域名、自动签发证书,听起来很美好,可一旦某个环节没按它的预期走,报错信息往往特别敷衍,甚至直接卡在Pending状态,你不知道它到底在等什么。再加上Vercel是面向全球开发者的产品,不少功能默认按欧美网络的习惯设计,很多策略对国内开发者来说并不友好。这就是暗坑存在的根源:不是Vercel这个平台不行,而是产品设计和你的预期之间经常出现错位。
我在实际使用里的感受是:大部分"翻车"不是Vercel出了bug,而是开发者对免费计划的边界、域名工作原理、Serverless runtime的限制理解不够。把这些底层逻辑搞明白,比记住一百个"点这个点那个"的教程有用得多。
1.2 这一篇要重点拆解的暗坑范围
上一篇已经把基础问题扫过一遍,所以这篇集中在四个更容易让人头疼的板块:
- 免费账号与计费策略的"隐形门槛",重点讲注册时容易被忽略的细节,以及哪些使用习惯会让免费额度漏得快。
- 绑定域名与DNS配置,这是热搜词"vercel绑定国内域名"背后真正的实操难点。主要讲国内域名服务商环境下,怎么配置解析才不会把域名搞废。
- Serverless函数和构建部署的坑,比如函数超时、请求体大小限制、框架识别失败、monorepo目录选错等。
- 常见报错的排查思路,以及我长期用下来总结的几条避坑习惯。
这篇文章不会教你从头到尾创建第一个Vercel项目,那个操作太简单了。重点是怎么在已经用起来之后,避免因为一些隐性规则导致线上故障、额度暴涨、或者域名解析一片混乱。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 免费账号与计费策略里的隐形门槛
2.1 vercel.com注册免费账号时最容易忽略的3个细节
先说注册。很多人看到"登录vercel.com注册一个免费账号"就顺手用邮箱注册了,但我的建议是尽量用GitHub账号登录,别用邮箱单独注册一个Vercel账号。原因很实际:用GitHub登录,之后导入仓库、配置自动部署都少一步授权操作,而且Vercel的账号体系跟GitHub组织、团队权限绑定得比较紧密,后续如果你要帮别人维护项目、或者把项目转给同事,GitHub登录的方式会灵活很多。
注册完之后,第一件事不是急着建项目,而是去设置页面确认你的Plan确实还是Hobby免费版。Vercel的界面经常在改版,有时候一些入口会引导你体验试用Pro计划,虽然很多是限时免费或者可退的,但如果你只是轻度使用,完全没必要去碰。我见过有人迷迷糊糊点了个试用的升级按钮,结果账单周期一到就扣了款,虽然申诉能退回,但整个过程挺糟心。
第三个容易忽略的细节是Team和个人账号的区别。Vercel的免费计划在个人账号下通常够用,但如果你创建了一个Team,不同Team之间是独立的额度池,有些功能权限也不一样。很多人注册完会顺手创建一个Team,然后把项目建在Team里,之后发现某些设置和免费额度范围跟个人项目不一样,又得把项目迁移出来,烦得很。建议个人项目直接放在个人账号下,不要一上来就建Team。
2.2 免费额度到底包括哪些,哪些行为会快速消耗
Vercel的免费计划(Hobby)不是简单地"随便用",它有几个比较关键的额度维度,而且官方经常调整具体数值,所以养成定期看Dashboard用量页的习惯比记住一个死数字更重要。但有几个方向的限制是长期存在的:
带宽是免费计划最容易被消耗的资源。Hobby计划每个月包含了100GB的带宽,听上去挺多,但一个稍微复杂点的页面首屏动辄几百KB甚至上MB,再加上图片、脚本、接口返回,一个真实用户访问几十次就可能吃掉几百MB。如果站点被爬虫扫一遍,或者有异常流量,100GB真的能在一两天内爆掉。很多人的Vercel项目突然显示Access Denied或者429 Too Many Requests,八成就是带宽超了。
Serverless函数的调用也有隐性成本。免费版不是让你无限跑函数的,它对你的函数执行总时长有一定限制,单位一般按GB-小时计。也就是说,函数内存越大、执行时间越长、调用次数越多,消耗越快。很多人喜欢在Vercel上跑爬虫定时任务或者轮询接口,这类低频但持续的操作,一个月累积下来其实很可观。
构建时长和日志保留时间也需要留意。免费版的构建小时数并不是无限的,虽然对个人项目来说通常够用,但如果你频繁推送代码、每推一次都触发重新构建,月底一看用量还是会吓一跳。更麻烦的是免费版的日志保留时间非常短,基本只够你"当时出问题当时去查",隔一天再回来翻日志,很可能就什么都没有了。
我最想提醒的是图片优化功能。Vercel的图片优化(也就是next/image默认走的那个Image Optimization API)会消耗带宽和缓存资源。很多人以为图片托管在外部图床就万事大吉,但next/image经过Vercel的处理链路时,还是会先经过Vercel的优化节点,所以带宽依然会从Vercel这边走。图片多的站点,带宽消耗速度比纯文字站快一个数量级。
2.3 防止免费额度爆掉的经验
额度爆掉不仅影响体验,还会让整个项目暂时不可访问,所以提前做防护比事后申诉省心得多。
第一,能上缓存就上缓存。如果只是静态内容或者变化不频繁的页面,可以考虑在Vercel前面加一层CDN做缓存,把静态资源的回源量压下来。Vercel本身自带CDN,但它的缓存策略要你在响应头里正确设置Cache-Control,否则每个请求都可能回源。我在vercel.json里给静态资源设置过比较激进的缓存策略,实测带宽消耗可以降一个数量级。
第二,善用Ignored Build Step,不要让每次push都触发构建。如果你只是在改README或者文档,完全没必要让Vercel重新部署一遍。Vercel支持在commit message里写[vercel skip]来跳过这次部署,也可以通过项目设置里的Ignored Build Step配置脚本,按分支、按文件变更范围决定要不要触发构建。这个习惯能帮你省下不少构建时长,也减少不必要的预览部署。
第三,不建议把Vercel当成免费的对象存储或者图床用。大文件、视频、安装包这类内容直接部署到Vercel,不仅部署体积容易超限,而且一被人访问就是大额带宽消耗。该放对象存储的就放对象存储,Vercel只负责前端页面和轻量接口,这样的架构才不容易在免费额度上翻车。
3. 绑定域名与DNS解析:国内域名怎么绑才不折腾
3.1 Vercel绑定域名的两种主流方案
Vercel上的自定义域名绑定,本质上就两种模式:一种是你继续用现有的DNS服务商,只在解析记录里加上Vercel要求的记录;另一种是把整个域名的NS托管交给Vercel,所有解析都由Vercel管理。很多人第一次操作时会在两者之间犹豫,我建议大多数情况下选第一种。
用"仅添加解析记录"的方式时,你需要在域名服务商后台配置两条核心记录:裸域(example.com)通常配置A记录指向76.76.21.21,子域(www等)配置CNAME记录指向cname.vercel-dns.com。这个方案的优点很明显:你现有的MX邮件记录、其他子域名的解析完全不受影响,改坏了也能秒回滚,风险非常小。
把NS改成Vercel提供的Nameserver是另一种思路。Vercel会告诉你把NS改成ns1.vercel-dns.com和ns2.vercel-dns.com,之后你在Vercel后台管理所有记录。这种方式的痛点是迁移成本高:一旦NS切换到Vercel,你原来域名邮箱、其他子站、第三方验证码用的TXT记录全都要手动迁到Vercel这边,漏一条就废一条。而且国内很多域名注册商对NS修改有一些限制或生效逻辑,切换之后想改回来也没那么快。
所以我在文章里的建议很明确:如果你的域名只用来挂Vercel上的网站,不需要邮箱和其他子服务,那两种方式都行;但只要你还在用这个域名接收邮件、跑其他服务,绝对不要轻易把NS交给Vercel。
3.2 国内域名服务商和解析平台的配置细节
"vercel绑定国内域名"这个热搜词对应的实际场景,通常是你在国内服务商购买了域名,然后想把站点部署到Vercel上。整个过程坑最多的环节不在Vercel,而在国内DNS控制台的操作细节。
第一,添加记录时要注意主机记录(主机名)的写法。裸域在大多数国内DNS后台要填@,www子域填www,别搞反。我见过不少人把裸域的记录写成了www,结果访问example.com永远打不开,Vercel后台的域名状态一直显示Invalid Configuration。
第二,CNAME记录和A记录在同一主机名下会冲突。比如你想把裸域example.com同时做CNAME和A记录,很多DNS服务商会直接提示冲突,要求你先删除一条。而对裸域来说,由于国内不少DNS服务商不支持CNAME Flattening,你往往只能用A记录指向76.76.21.21,而不是像Vercel官方文档写的那样直接用CNAME。
第三,TTL值建议调小一点。初次配置时TTL设成600秒左右,方便你改了记录后快速验证。等确认没问题了,再把它调大到3600甚至更长,减少DNS查询压力。
第四,域名添加到Vercel之后,状态经常是Pending Verification。这个状态不一定代表配置错了,更常见的是DNS记录还没生效。国内DNS的生效时间从几分钟到几小时不等,如果半小时后还是Pending,多半是记录值写错了,回到DNS控制台重新核对一下。Vercel的验证机制会定时检查,所以不用反复删除再添加,你只需要确认记录内容正确、TTL过了之后等它自动变成Valid。
3.3 域名相关的暗坑:子域名、邮箱、HTTPS证书
很多人在Vercel上绑定域名成功后,就以为一劳永逸了,其实还有几个隐藏雷区。
最常见的坑是证书自动签发失败。Vercel对自定义域名会自动申请HTTPS证书,但它依赖DNS记录正常解析,并且需要能通过CAA记录的校验。如果你的域名在DNS服务商那里配置过CAA记录,限制了证书颁发机构,Vercel的证书申请就会被拒掉,域名一直停留在安全警告状态。排查方法是检查DNS里有没有CAA记录,如果有,你得允许Let's Encrypt这个CA颁发证书。
第二个坑是域名所有权验证。有些域名后缀或注册局要求先验证你确实拥有这个域名,Vercel会给你一个TXT记录值,让你在DNS后台添加一条vercel-verification的TXT记录。这一步很容易被跳过,因为Vercel的提示有时候藏在域名详情页的角落里。添加完TXT记录后,要等DNS生效,Vercel验证通过后这个TXT记录就可以删掉,也可以留着。
第三个坑跟域名的其他用途有关。如果你的域名还在跑邮箱,比如域名邮箱绑定了MX记录、设置了SPF/DKIM的TXT记录,那么你的解析后台里必须保留这些记录。很多人为了配Vercel,直接把NS切到Vercel,域名邮箱第二天就收不到信了。这种情况我见过太多次,排查到最后发现是NS迁移导致MX和SPF记录全丢了。
第四个坑是关于子域名的。你在Vercel上绑定了一个域名后,它不会自动处理别的子域名。比如你绑定了example.com,又想让blog.example.com也指向Vercel,那要在Vercel项目里单独添加这个子域,再在DNS后台配好对应的CNAME记录。Vercel不会凭空帮你把子域都解析过来,很多人想当然地配了个通配符,反而把其他子服务搞乱了。
4. Serverless函数与部署流程的核心暗坑
4.1 Serverless函数在免费版里的硬限制
Vercel的Serverless函数确实很方便,写个API接口、处理表单、做点轻量后端逻辑都能直接跑,但它在免费版里的限制比大多数人以为的要严格。
第一是执行时长。免费版函数默认的最大执行时长很短,默认应该在10秒级别,超过就会报Function Timed Out。如果你在里面跑数据库查询、调外部API、处理大文件,经常莫名其妙超时。解决办法有两个:一是优化函数逻辑,把同步操作改成异步或拆分;二是在项目里显式配置maxDuration,但也要注意套餐上限,免费版再怎么配也不可能超过它给你的最大值。
第二是请求体大小。Vercel函数对请求体有大小限制,好像是4.5MB左右,超过直接拒掉。这个限制对纯JSON接口一般够用,但如果你打算用Serverless函数接收文件上传、或者接收Base64图片,很容易触发。很多人的"部署在Vercel的上传功能挂了",根源都在这里。正规做法是上传走对象存储,Vercel函数只生成预签名URL,别在函数体里做大流量传输。
第三是临时文件系统。函数在运行时会给你一个临时目录/tmp,但它不是持久化磁盘,实例结束数据就没了,而且不同函数、不同请求之间都不能共享。有人把Session文件写进/tmp,或者拿/tmp当缓存目录,结果请求一多就出现诡异的数据错乱,这就是没搞懂它是一次性的。需要持久化的数据,应该用数据库或对象存储。
第四是Edge函数的运行时限制。Vercel有两类函数:标准Node.js函数和Edge Runtime函数。Edge函数部署在边缘节点、响应更快,但它的运行时不是完整Node,不包含fs、path、crypto这类Node内置模块,也不能直接用大部分Node依赖。如果你把一段依赖Node能力的代码放到Edge函数里,运行时会直接报Cannot find module。排查方法很简单:看报错里是不是提到了Node内置模块,如果是,就把这个函数改成Node.js Runtime,或者把相关逻辑抽出去放到独立接口里。
第五是环境变量的大小限制。Vercel的环境变量不是无限长的,单个环境变量的值如果特别大(比如塞了一整份JSON配置、长密钥),保存时可能被截断或报错。要放大量配置,建议用配置服务或者直接打包进项目里构建时注入,不要堆在环境变量里。
4.2 前端框架部署时的构建与目录坑
Vercel的自动框架识别确实好用,但并不是每次都能猜对。我遇到过的典型情况是:Vue项目构建时,Vercel没识别出Vite,直接当成Other项目处理,Build Command是空的,Output Directory也是空的,结果部署出来一个空页面。
遇到这种情况,要在项目设置里手动指定框架预设,或者手填构建命令和输出目录。Vite项目通常构建命令是npm run build,输出目录是dist;Create React App输出目录是build;Next.js静态导出时输出目录是out,同时需要在next.config里设置output: 'export'。这些配置在Vercel的项目设置页面都有,直接在Build Settings里改即可。
还有一个常见的坑是monorepo。如果你在一个仓库里放了多个子项目,Vercel默认会以仓库根目录为项目根目录,结果它找不到package.json,或者找到了但构建的是错误的子项目。解决办法是在项目设置里的Root Directory里指定子项目的路径,比如apps/web。注意,这个路径是相对于仓库根目录的,填错了整个构建都起不来。
我建议所有配置尽量通过项目里的vercel.json来声明,而不是只依赖页面设置。vercel.json放在项目根目录,配置直观,而且改起来可以走Git历史。比如指定构建命令和输出目录,可以这样写:
json复制{
"buildCommand": "npm run build",
"outputDirectory": "dist",
"installCommand": "npm install"
}
本地跑得好好的,部署就是挂,这种问题十有八九出在环境差异上。常见原因有三个:一是lock文件不一致,本地用npm考的lock传上去Vercel换pnpm装,版本对不上;二是Node版本不同,Vercel默认的Node版本可能和本地有差异,某些API行为不一样;三是依赖里有用到原生模块,构建机器和本地架构不同,编译失败。解决方法是尽量在package.json里锁定packageManager字段,并且在Vercel项目设置里明确Node.js版本,让它和本地一致。
Next.js项目的坑要单独说。很多人在Next.js项目里用了Server Actions或者Route Handlers,但又在设置里配了静态导出,结果构建时报错,因为静态导出不支持服务端运行时的功能。反过来,如果你只想部署一个纯静态站点,却忘了配output: 'export',Vercel会把它当作需要Serverless函数支撑的完整Next.js应用,构建产物会和预期不一致,还会白白增加函数调用和带宽消耗。
4.3 环境变量与日志排查的心得
环境变量在Vercel上的行为,很多人第一次接触时会理解偏。最核心的一条是:只有以特定前缀开头的环境变量才会被暴露到前端代码里。在Next.js里,NEXT_PUBLIC_前缀的变量可以在浏览器端访问;而不带这个前缀的变量只在服务端函数里存在。如果你把一个没有前缀的密钥放在环境变量里,然后试图在客户端代码里读取它,结果是undefined。反过来,如果你把密钥加上了NEXT_PUBLIC_前缀,它就是明文暴露在浏览器里的,等于把密码贴在门上。
另一个容易踩的坑是:修改环境变量后,必须重新部署才会生效。很多人改了环境变量,保存之后马上刷新线上页面,发现还是旧值,以为Vercel出问题了。实际上Vercel的环境变量是在构建时注入的,你改完变量之后,需要重新触发一次部署,构建出来的产物才会带上新值。这个逻辑跟本地开发时的.env文件自动读取不太一样,很多人一开始都不适应。
日志方面,前面说过免费版的日志保留时间很短,所以排查问题的窗口期其实有限。我的习惯是:上线阶段如果发现接口报错,第一时间去Vercel后台的Function Logs里看,别等到第二天再查。为了弥补日志保留短的缺陷,我会在关键函数里把重要错误上报到第三方错误监控服务,至少保证即使Vercel日志被清掉了,我还能知道某个接口挂在了哪一步。用起来之后你会发现,这个投入比每天蹲在Vercel后台刷日志值太多了。
还有一个部署日志相关的常见报错:The Edge Function "middleware" is too large。这个跟Vercel的Edge函数代码包大小限制有关。很多时候是因为你把不必要的依赖引入了中间件或Edge函数,打包体积一下就超了。排查思路是把Edge函数里的逻辑做减法,只留轻量的路由跳转和请求改写,重逻辑放到普通的Serverless函数里。
5. 常见问题排查与避坑心得
5.1 典型报错速查表
这里把我自己见过、以及帮别人排查过的高频报错整理成一张表,方便你硬核对照。
| 报错或现象 | 背后原因 | 处理方式 |
|---|---|---|
| Invalid Domain Configuration | DNS记录值不对或未生效 | 核对A/CNAME记录值与TTL,等待生效后重新验证 |
| Your DNS has not been configured correctly | 域名解析没指向Vercel | 检查裸域和子域记录是否混用,按3.2节方式重配 |
| Pending Verification持续时间过长 | TXT验证记录或CAA记录有问题 | 确认是否缺少vercel-verification的TXT记录,检查CAA是否阻止签发 |
| Function Timed Out | 函数执行超过套餐时长上限 | 优化函数逻辑,显式配置maxDuration,必要时拆分任务 |
| Function request body size limit exceeded | 上传或请求体超过4.5MB | 改为对象存储直传或分片提交 |
| Cannot find module 'fs' / 'path' | Edge Runtime里用了Node内置模块 | 改成Node.js Runtime,或把该逻辑移出Edge函数 |
| Failed to detect framework | 框架自动识别失败 | 在Build Settings里手动指定构建命令和输出目录 |
| 本地正常,部署后空白页 | 输出目录填错或构建命令不对 | 确认Output Directory和Build Command正确 |
| 修改环境变量后不生效 | 环境变量是构建时注入的 | 修改后必须重新部署一次 |
| 429 Too Many Requests | 免费额度超限 | 检查带宽和函数消耗,配置缓存和Ignored Build Step |
| The Edge Function is too large | Edge函数打包体积超限 | 移除无关依赖,只保留轻量逻辑在Edge里 |
5.2 我自己压箱底的几条经验
这篇写了这么多,最后分享几条我在实际项目里沉淀下来的习惯,算不上什么高深技巧,但确实帮我少踩了很多坑。
第一个习惯是:任何新项目上线前,先把域名和DNS方案定下来,再写代码。很多人是先写代码、推到GitHub发现可以自动部署,然后临时去绑域名,结果在DNS上折腾一整天。域名解析看起来是最后一步,实际上它影响你对整个项目的访问测试、HTTPS证书、以及后续的迁移方案。先想清楚裸域、www、子域要指向哪里,后面会轻松很多。
第二个习惯是:能用vercel.json和代码配置搞定的,绝对不在线上后台手点。原因很简单,后台操作不可追溯,改了什么没人记得清白。而vercel.json、next.config、package.json里的配置都有Git记录,出了问题可以快速回滚看差异。建议把关键配置都落到项目里,后台面板只用来查日志和看用量。
第三个习惯是:在本地模拟Vercel的构建环境。Vercel的CLI提供了vercel dev和vercel build,前者可以在本地模拟Serverless函数和边缘网关,后者可以完整跑一遍构建流程。我现在的流程是:本地先vercel build,确认没有构建错误,再推到GitHub触发线上部署。这个习惯能过滤掉一大半"本地好端端部署就挂"的问题,尤其是Node版本、环境变量、依赖安装这类环境差异问题。
第四个习惯是:免费计划也要有成本意识,但不是让你节衣缩食。Vercel免费计划的设计逻辑是让你"体验和试跑",不是让你无限白嫖生产流量。如果你只是做实验、写Demo,它非常合适;如果你的项目已经进入了正式运营阶段,对稳定性、带宽和日志有要求,那确实得考虑升级计划或者把架构做拆分,比如把大文件放到对象存储、把函数改成边缘函数、把日志接到第三方。硬撑在免费计划上,随时可能因为一次流量波动就打不开站,这并不划算。
第五个习惯,也是我反复强调的:不要把所有鸡蛋放在一个篮子里。Vercel再好用,它也只是你部署链路里的一环。域名注册、DNS解析、构建部署、数据存储、日志监控这些环节,尽量保持耦合度低一点。你会发现,一旦某个环节出了问题,解耦后的架构能让你快速切换方案,而不是被绑在单一平台上动弹不得。
我用Vercel做个人项目和小团队项目也有几年了,整体来说它依然是目前不可多得的省心平台。但正是因为它把事情自动化得太彻底,使用者反而需要更清楚背后的机制。暗坑总结再多,都不如自己动手排查一次来得实在。下次再在Vercel上遇到问题,建议先按这篇的思路拆开看:是免费额度的限制、DNS配置的问题,还是Serverless运行时和构建流程的误解,大概率能省下不少排查时间。
