
关于
使用 Next.js 部署到 Vercel 的专家知识。
name: vercel-deployment description: 使用 Next.js 部署到 Vercel 的专业知识 risk: safe source: vibeship-spawner-skills (Apache 2.0) date_added: 2026-02-27
Vercel 部署
使用 Next.js 部署到 Vercel 的专业知识
能力
- vercel
- deployment
- edge-functions
- serverless
- environment-variables
前置条件
- 必需技能:nextjs-app-router
模式
环境变量设置
为所有环境正确配置环境变量
何时使用:在 Vercel 上设置新项目时
// Vercel 中的三个环境:
// - Development(本地)
// - Preview(PR 部署)
// - Production(main 分支)
// 在 Vercel 仪表板中:
// Settings → Environment Variables
// PUBLIC 变量(暴露给浏览器)
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
// PRIVATE 变量(仅服务端)
SUPABASE_SERVICE_ROLE_KEY=eyJ... // 绝不要加 NEXT_PUBLIC_!
DATABASE_URL=postgresql://...
// 按环境区分的值:
// Production:真实数据库,生产 API 密钥
// Preview:暂存数据库,测试 API 密钥
// Development:本地/开发值(也在 .env.local 中)
// 在代码中检查环境:
const isProduction = process.env.VERCEL_ENV === 'production'
const isPreview = process.env.VERCEL_ENV === 'preview'
Edge vs Serverless 函数
为你的 API 路由选择正确的运行时
何时使用:创建 API 路由或中间件时
// EDGE 运行时 - 快速冷启动,有限的 API
// 适用于:认证检查、重定向、简单转换
// app/api/hello/route.ts
export const runtime = 'edge'
export async function GET() {
return Response.json({ message: 'Hello from Edge!' })
}
// middleware.ts(始终是 edge)
export function middleware(request: NextRequest) {
// 在此进行快速认证检查
}
// SERVERLESS (Node.js) - 完整 Node API,较慢的冷启动
// 适用于:数据库查询、文件操作、重计算
// app/api/users/route.ts
export const runtime = 'nodejs' // 默认值,可省略
export async function GET() {
const users = await db.query('SELECT * FROM users')
return Response.json(users)
}
构建优化
优化构建以实现更快的部署和更小的包体积
何时使用:准备生产部署时
// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
// 最小化输出
output: 'standalone', // 用于 Docker/自托管
// 图片优化
images: {
remotePatterns: [
{ hostname: 'your-cdn.com' },
],
},
// 包分析器(仅开发)
// npm install @next/bundle-analyzer
...(process.env.ANALYZE === 'true' && {
webpack: (config) => {
const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
config.plugins.push(new BundleAnalyzerPlugin())
return config
},
}),
}
// 减少 serverless 函数大小:
// - 对重型库使用动态导入
// - 使用以下命令检查包:npx @next/bundle-analyzer
预览部署工作流
使用预览部署进行 PR 审查
何时使用:设置团队开发工作流时
// 每个 PR 自动获得唯一的预览 URL
// 用密码保护预览部署:
// Vercel Dashboard → Settings → Deployment Protection
// 为预览使用不同的环境变量:
// - PREVIEW:使用暂存数据库
// - PRODUCTION:使用生产数据库
// 在代码中检测预览:
if (process.env.VERCEL_ENV === 'preview') {
// 显示 "Preview" 横幅
// 使用测试支付处理器
// 禁用分析
}
// 在 PR 上评论预览 URL(Vercel GitHub 集成自动完成)
自定义域名设置
配置带有正确 SSL 的自定义域名
何时使用:上线生产时
// 在 Vercel Dashboard → Domains
// 添加域名:
// - example.com(顶级/根域名)
// - www.example.com(子域名)
// DNS 配置(在你的域名注册商处):
// Type: A, Name: @, Value: 76.76.21.21
// Type: CNAME, Name: www, Value: cname.vercel-dns.com
// 重定向 www 到顶级域名(或反之):
// Vercel 自动处理
// 在 next.config.js 中配置重定向:
module.exports = {
async redirects() {
return [
{
source: '/old-page',
destination: '/new-page',
permanent: true, // 308
},
]
},
}
注意事项
NEXT_PUBLIC_ 会将密钥暴露给浏览器
严重性:严重
情况:对敏感 API 密钥使用 NEXT_PUBLIC_ 前缀
症状:
- 密钥在浏览器 DevTools → Sources 中可见
- 安全审计发现暴露的密钥
- 来自未知来源的意外 API 访问
原因: 以 NEXT_PUBLIC_ 为前缀的变量在构建时被内联到 JavaScript 包中。任何人都可以在浏览器 DevTools 中查看它们。这包括你所有的用户和潜在的攻击者。
推荐修复:
仅对真正公开的值使用 NEXT_PUBLIC_:
// 安全使用 NEXT_PUBLIC_
NEXT_PUBLIC_SUPABASE_URL=https://xxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ... // Anon key 设计为公开的
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_live_...
兼容工具
Claude CodeCursor
标签
后端开发
