很多前端团队在功能分支开发初期靠本地环境,需求进入联调后就开始抢一个共享 staging。测试同学经常问“最新代码在哪个环境”?一个需求没测完,另一个分支已经被别人部署上去了。Vercel Preview Deployment 这类工作流逐步成为前端工程化中的重要一环,核心做法是让每个 PR 都获得一个临时、独立的部署地址,环境与代码改动一一对应。这也是本文想聊清楚的问题:它到底解决了什么,实际落地时有哪些门道。

为什么每个 PR 需要一个独立环境?
共享环境最大的问题,是环境状态和代码状态不匹配。多个分支同时构建,部署结果互相覆盖;上一轮联调挂在半路的用例,下一轮已经被新代码冲掉了。测试人员在 staging 上发现的问题,未必是当前分支引入的,也可能是另外一条分支提前合入的。这种混乱在团队规模扩大之后会迅速放大。
真正麻烦的地方不只是“环境不够用”,而是代码评审环节缺失了“可运行版本”。Pull Request 里可以看到 diff、可以评代码结构,但前端最核心的交互效果,靠肉眼看代码很难判断。尤其是视觉调整、动效细节、响应式布局,reviewer 往往需要把分支拉下来跑一遍才有体感。Preview Deployment 把这一步简化为点击一个链接。
一个比较典型的小团队场景是这样的:团队有四五个前端需求同时在开发,staging 环境只有一个,测试 A 功能时 B 分支已经被构建上去覆盖了。不得已之下,大家只能约定“谁要测就先跟别人打招呼”,再手动切换分支重新部署。引入 Vercel 的 Preview Deployment 之后,每个 PR 都会生成独立 URL,测试人员和产品经理可以直接基于对应分支的产物提反馈,联调效率提升得很明显。
Preview Deployment 是怎么运作的?
Vercel 的 Preview Deployment 并不复杂。它通过 Git 集成监听 push 和 PR 事件,检测代码变更后自动执行构建,然后为每次构建分配一个全局唯一的 URL。这个 URL 会被自动回填到 Pull Request 的评论中,并且随着新 commit 的推送持续更新。开发者的常规流程并不会被打断,提交代码、看评论、点链接打开预览页面,仅此而已。
在简单项目里,Vercel 会自动识别框架,几乎不需要额外配置。但对于 Monorepo 或者有多入口的前端工程,直接使用默认集成可能不够。比如一个仓库里同时存在 admin 和 portal 两个应用,改动 admin 目录时并不需要重新构建 portal。此时可以用 Vercel CLI 在 CI 中手动创建 preview deployment,只构建受影响的 workspace:
vercel pull --yes --environment=preview --token=$VERCEL_TOKEN
vercel build --cwd apps/web --token=$VERCEL_TOKEN
vercel deploy --prebuilt --cwd apps/web --token=$VERCEL_TOKEN
这段流程的关键在于 --prebuilt:它允许你在本地或者自建 CI 中先构建好产物,再交给 Vercel 分配 URL 和托管。这样既能保留 Vercel 对部署生命周期的管理,又能让构建过程待在自己的构建系统里。
如果是更大规模的 Monorepo,最好再给构建步骤加一层路径过滤。Vercel 支持在项目配置里设置 Ignore Build Step,用脚本判断本次变更是否真正涉及当前应用。一个常见做法是检查 git diff:
git diff --name-only HEAD^ HEAD | grep -q 'apps/web/' && exit 0 || exit 1
如果本次提交没有改动 apps/web 下的任何文件,脚本直接返回 1,Vercel 就会跳过这次部署。这一层控制很值得加,尤其是在团队活动频繁、仓库内应用较多的阶段,能省下大量构建时间和账单费用。
工程化实践中需要配置好的几件事
Preview Deployment 不是一个开箱即完的功能,它有几个地方需要团队提前约定清楚。
- 环境变量的级别。Vercel 区分 Production、Preview 和 Development 三个环境。Preview 环境必须使用独立的数据库、独立的对象存储,绝不能直接复用生产连接串。一个常见的错误是直接把生产数据库连接配到 Preview 上,结果测试数据污染了线上业务数据。
- 访问权限控制。每生成一个 URL 就等于对外暴露了一个线上可访问页面。未发布功能可能包含敏感数据,Vercel 的 Deployment Protection 可以要求访问者通过登录验证,也可以接 Auth0 等第三方认证。建议对非公开项目一律开启保护。
- 部署目标分支。Preview Deployment 针对的是 PR 分支,而不是所有分支。建议只保留 PR 触发,普通 push 不做预览部署,避免本地频繁推送把整个构建队列占满。
- 部署后清理策略。PR 合并后,对应的 Preview URL 不会立刻消失。Vercel 默认会保留一段时间,但团队最好设置自动删除旧部署,防止链接被遍历访问到过期代码。
Preview Deployment 常见的四个误区
真正用起来之后,有些问题才开始浮现。这里列几个我在工程里看到过很多次的坑。
- 把 Preview 当成生产环境来用。Preview 部署的运行时资源往往比生产环境小,数据库也是独立轻量的。你在预览环境里看到的执行结果不能代表生产环境的真实表现。不要拿它做压测,也不要因为它“可以访问”就把它当成 staging 的替代品。
- 忽略 Serverless 函数的行为差异。Vercel 上的 Preview Deployment 也会部署你的 API 路由和 Edge Functions,但环境变量、地域、超时时间都可能与 Production 不同。如果前端请求的 URL 里硬编码了 preview 域名,后续又希望用同一套代码打开生产链接,会踩跨域或路径不匹配的坑。
- 不限制 Preview 环境的成本。一个 PR 对应一个环境,如果团队活动频繁,整个仓库的构建次数会快速上升。Vercel 的免费额度之外,额外构建和带宽都是按量计费的。没有路径过滤和自动清理的话,月底账单会很难看。
- 让 Preview URL 成为拍板依据。产品团队拿预览页面做视觉验收是合理的,但要知道它背后的配置可能与正式环境不同。比如某个功能依赖第三方登录或支付,预览环境往往没有完整模拟,界面看起来正常,真正上线时还是会出问题。
这里有一个真实感很强的教训:之前有个团队联调支付回调,第三方网关要求配置回调地址白名单。由于 Preview Deployment 的 alias 随 PR 变动,每次他们重新生成预览 URL,都得去网关白名单里加一条,联调效率很低。后来给重要 PR 固定了 alias,才避免在环境链接上反复折腾。这也是我要单独强调的点:如果依赖第三方回调,Preview URL 的稳定性很重要。
和 Netlify、自建 CI/CD 相比怎么选?
其实 Preview Deployment 这个思路并不是 Vercel 首创,Netlify 的 Deploy Previews 和很多自建方案都能做到。区别在于各自对前端工作流的适配深度。
| 对比维度 | Vercel Preview | Netlify Deploy Previews | 自建 CI/CD 临时环境 |
|---|---|---|---|
| Git 集成 | 深度集成,开箱即用 | 集成度较高 | 需要自己接入 Git 事件和 Provider |
| 权限控制 | 支持团队级和站点级保护 | 支持基础密码保护 | 取决于自建体系,通常要自己实现 |
| Serverless 支持 | 原生支持边缘函数和函数 | 支持函数,但生态弱一些 | 可接任意容器或函数平台 |
| 适合场景 | Next.js、前端应用团队 | 静态站点、Jamstack | 已有 K8s 或复杂后端依赖的团队 |
如果你的业务深度依赖 Next.js,或者团队还要求 preview 环境里能同步看到 API 和前端,Vercel 的完整闭环是有优势的。自建方案的优势在于环境保真度。比如你的后端包含微服务、消息队列、数据库迁移,那 Preview 环境应该把这些组件一并拉起,而 Vercel 只能承载靠近前端的部分。这种情况下,自建一个临时命名空间并用脚本注入到 CI,会更可控。
让 Preview Deployment 真正融入协作流程
落地 Preview Deployment 不能只在 Vercel 控制台开启开关,还需要把它放入代码评审和联调习惯里。我比较推荐这样几步。
- 在分支模型上区分 preview 和 production:推送带
refs/pull/*的分支只构建 Preview,打 tag 或推主分支时走 Production。 - 把 Vercel 部署状态接入 GitHub Checks。这样 PR 页面上可以看到部署状态,E2E 测试可以等待部署完成后再运行,避免在旧版本上白白跑一遍。
- 在 IM 群或项目文档中固化“预览链接的获取方式”,减少团队内部的沟通成本。
- 给重要的 PR 需求配置固定的“预览域名”,方便第三方回调。比如支付回调或 OAuth 跳转需要白名单,如果每次 URL 变化,联调成本会升高。Vercel 支持的 Alias 机制可以解决这个问题。
最后说一点我的个人感受。Preview Deployment 改变的并不只是部署方式,它让前端协作里那些说不清的“等你拉下来跑跑看”变成了一个可传播的链接。每个 PR 一个环境,其实就是把“看代码”和“看效果”的语义彻底分开了。代码评审依然要看 diff,但交互确认可以直接交给预览页面。它当然不是万能的,生产环境的问题最终还要靠生产环境发现,但至少在日常联调和设计走查这条链路里,它把很多无意义的等待移除掉了。如果你的团队目前还在为共享环境吵架,值得找一个项目先试一把。
原创文章,作者:fudengji,如若转载,请注明出处:https://fudengji.cn/article/766/