Vercel:前端部署的首选平台

NOTE

本文档最后更新于 2026年4月,涵盖 Vercel 平台架构、Edge Network、Serverless Functions、Next.js 部署配置、环境变量、Analytics,以及与 Cloudflare Pages/Netlify 的对比分析。


Vercel 是什么

平台定位与核心理念

Vercel 由 Guillermo Rauch 于 2015 年创立,这位创始人同时也是广受欢迎的 Node.js 框架 Next.js 的创造者。Vercel 最初的名字叫 ZEIT,2020 年更名为 Vercel,并在同年获得了大量关注——因为 Next.js 的爆火让 Vercel 成为了前端部署领域最炙手可热的平台。

Vercel 的核心理念可以用三个词概括:极简、自动、全球

极简体现在零配置部署上。你不需要写任何 CI/CD 配置文件,不需要管理服务器,不需要配置负载均衡,只需要把代码 push 到 GitHub,Vercel 自动检测项目类型、运行构建、部署上线。第一次使用时这个体验确实会让人眼前一亮——原来部署可以这么简单。

自动体现在预览部署上。每次创建 Pull Request,Vercel 自动生成一个独立的预览 URL,团队成员可以在合并前看到实际效果。这彻底改变了 code review 的流程——不再只是看代码改动,而是可以直接在真实环境中测试。

全球体现在 Edge Network 上。Vercel 在全球 70 多个城市部署了边缘节点,用户请求会被路由到最近的数据中心,响应延迟极低。

Vercel 能部署什么

Vercel 对前端框架的支持非常全面,最核心的当然是 Next.js,但也不限于此:

React 框架:Next.js(原生支持,深度优化)、Create React App、Vite、Remix
Vue 框架:Nuxt、Vue
Svelte 框架:Svelte、SvelteKit
静态站点:Next.js(SSG)、Astro、Gatsby、Hugo、Eleventy
全栈应用:Next.js API Routes、Nest.js、RedwoodJS
其他:Angular、Express 等任何可以构建为静态资源或 Serverless 的项目

对于 Next.js 项目来说,Vercel 是绝对的首选——因为 Next.js 就是 Vercel 团队开发的,所以在框架更新和新特性支持上,Vercel 总是第一个吃螃蟹的。


技术架构:请求是如何被处理的

整体架构

当你访问一个托管在 Vercel 上的网站时,请求会经过一个精心设计的路由网络:

用户发起请求(https://myapp.vercel.app)
        │
        ▼
    DNS 解析
        │
        ▼
    全球 CDN 边缘节点(最近的 PoP)
        │
        ├─ 静态资源(如 JS/CSS/图片)
        │   → 直接从 CDN 缓存返回(极快)
        │
        └─ 动态请求
            │
            ▼
        Regional Edge(区域计算节点)
            │
            ├─ ISR 页面 → 返回缓存的 HTML
            │
            ├─ SSR → 执行 Serverless Function
            │
            └─ API Routes → 执行 API 函数
                    │
                    ▼
                可能的后端服务(数据库、缓存)
                    │
                    ▼
                响应返回(经过 CDN 缓存优化)

这个架构的精妙之处在于分层处理:不需要计算的静态资源直接从边缘 CDN 返回,需要计算的才路由到区域计算节点。CDN 缓存命中率高的话,大部分请求根本不需要到达 Serverless Functions 层,成本和延迟都大幅降低。

Serverless Functions vs Edge Functions

Vercel 提供两种计算模式,理解它们的区别很重要:

Serverless Functions 运行在传统的 Node.js 环境中,冷启动大约 100-500 毫秒,执行时间限制在免费版 10 秒、付费版 60 秒(可配置到 300 秒)。它们适合需要复杂业务逻辑、数据库操作、文件处理等 CPU 和 IO 密集型的任务。

Edge Functions 运行在 V8 隔离区中,冷启动只需 1-5 毫秒,执行时间限制 50 毫秒。它们适合轻量级的处理逻辑:路由重写、访问控制、A/B 测试、地理位置判断等。Edge Functions 牺牲了执行时间换取极低的响应延迟。

对比维度Serverless FunctionsEdge Functions
冷启动时间100-500ms< 5ms
执行时间限制10-300s50ms
运行环境Node.jsV8 Isolates
支持的 API完整的 Node.js APIFetch API(受限)
支持的 npm 包所有 npm 包有限(轻量的包)
适用场景复杂业务逻辑、数据库操作路由、中间件、A/B 测试
成本按执行时间计费按请求数计费(更便宜)

在实际项目中,一个常见的设计模式是:Edge Functions 处理路由和访问控制(放在前面,响应快),Serverless Functions 处理实际的数据库查询和业务逻辑(放在后面,能力强)。


部署你的第一个项目

三种部署方式

Vercel 提供了三种部署方式,从简单到灵活排序:

方式一:通过 GitHub 直接导入(最推荐)

这是 Vercel 的核心使用方式。访问 vercel.com/new,选择你的 GitHub 仓库,Vercel 自动检测项目类型并配置构建命令。整个过程不到一分钟,之后每次 push 到指定分支都会自动触发新的部署。

方式二:Vercel CLI

适合喜欢在终端里完成一切的开发者:

# 全局安装 CLI
npm install -g vercel
 
# 登录
vercel login
 
# 在项目目录中初始化
cd my-project
vercel
 
# 部署到生产环境
vercel --prod

方式三:Dashboard 上传

直接拖拽文件夹到网页上,适合临时演示或不想连接 GitHub 的场景。

Next.js 项目配置

Vercel 对 Next.js 项目提供了开箱即用的支持,但一些高级配置需要手动设置:

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  // 图片优化配置
  images: {
    remotePatterns: [
      {
        protocol: "https",
        hostname: "images.unsplash.com",
      },
      {
        protocol: "https",
        hostname: "*.amazonaws.com",
      },
    ],
    formats: ["image/avif", "image/webp"],
    deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048],
  },
 
  // 编译优化
  compiler: {
    removeConsole: process.env.NODE_ENV === "production",
  },
 
  // 重定向规则
  async redirects() {
    return [
      {
        source: "/old-blog/:slug",
        destination: "/blog/:slug",
        permanent: true, // 301 重定向
      },
    ];
  },
 
  // Header 配置
  async headers() {
    return [
      {
        source: "/(.*)",
        headers: [
          {
            key: "X-Frame-Options",
            value: "DENY",
          },
          {
            key: "X-Content-Type-Options",
            value: "nosniff",
          },
        ],
      },
    ];
  },
 
  // 实验性特性
  experimental: {
    optimizePackageImports: ["lucide-react", "recharts", "date-fns"],
  },
};
 
module.exports = nextConfig;

Serverless Functions 实战

API Routes 基础

Next.js 的 API Routes 功能允许你在 Next.js 应用中直接创建 API 端点,部署时会自动转换为 Serverless Functions:

// app/api/users/route.ts
import { NextRequest, NextResponse } from "next/server";
import { prisma } from "@/lib/prisma";
 
// GET 请求处理
export async function GET(request: NextRequest) {
  const { searchParams } = new URL(request.url);
  const page = parseInt(searchParams.get("page") || "1");
  const limit = parseInt(searchParams.get("limit") || "10");
  const search = searchParams.get("search") || "";
 
  const where = search
    ? {
        OR: [
          { name: { contains: search, mode: "insensitive" } },
          { email: { contains: search, mode: "insensitive" } },
        ],
      }
    : {};
 
  const [users, total] = await Promise.all([
    prisma.user.findMany({
      where,
      skip: (page - 1) * limit,
      take: limit,
      orderBy: { createdAt: "desc" },
      select: {
        id: true,
        name: true,
        email: true,
        image: true,
        createdAt: true,
      },
    }),
    prisma.user.count({ where }),
  ]);
 
  return NextResponse.json({
    users,
    pagination: {
      page,
      limit,
      total,
      pages: Math.ceil(total / limit),
    },
  });
}
 
// POST 请求处理
export async function POST(request: NextRequest) {
  const body = await request.json();
  const { name, email } = body;
 
  if (!name || !email) {
    return NextResponse.json(
      { error: "Name and email are required" },
      { status: 400 }
    );
  }
 
  try {
    const user = await prisma.user.create({
      data: { name, email },
    });
 
    return NextResponse.json(user, { status: 201 });
  } catch (error) {
    if ((error as { code?: string }).code === "P2002") {
      return NextResponse.json(
        { error: "User with this email already exists" },
        { status: 409 }
      );
    }
    throw error;
  }
}

函数配置与性能调优

可以通过 vercel.json 为不同的函数设置不同的资源配置:

{
  "functions": {
    "app/api/basic/**/*.ts": {
      "maxDuration": 10,
      "memory": 1024,
      "regions": ["iad1"]
    },
    "app/api/ai/**/*.ts": {
      "maxDuration": 60,
      "memory": 3008,
      "regions": ["iad1"]
    },
    "app/api/export/**/*.ts": {
      "maxDuration": 300,
      "memory": 2048
    }
  }
}

Edge Functions 与中间件

中间件基础

Next.js 的中间件(Middleware)运行在 Edge Functions 环境中,可以在请求到达页面之前执行逻辑:

// middleware.ts
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
 
export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;
 
  // 基于 cookie 实现 A/B 测试分组
  let group = request.cookies.get("ab-group")?.value;
  if (!group) {
    group = Math.random() > 0.5 ? "A" : "B";
    const response = NextResponse.next();
    response.cookies.set("ab-group", group, {
      maxAge: 60 * 60 * 24 * 30,
      path: "/",
    });
    response.headers.set("X-AB-Group", group);
    return response;
  }
 
  // 为 B 组用户重写到 beta 页面
  if (pathname === "/" && group === "B") {
    return NextResponse.rewrite(new URL("/beta", request.url));
  }
 
  // 检查受保护路径的登录状态
  if (pathname.startsWith("/dashboard")) {
    const token = request.cookies.get("auth-token")?.value;
    if (!token) {
      const loginUrl = new URL("/login", request.url);
      loginUrl.searchParams.set("redirect", pathname);
      return NextResponse.redirect(loginUrl);
    }
  }
 
  // 添加安全头
  const response = NextResponse.next();
  response.headers.set("X-Custom-Header", "value");
  return response;
}
 
export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
};

中间件实战用例

中间件的典型使用场景非常丰富:地理定位重定向,根据用户所在地区跳转到对应语言或版本的页面;Bot 检测,识别爬虫并返回不同内容或直接拒绝访问;速率限制,在边缘层拦截过多请求;JWT 验证,在请求到达 Serverless Function 前验证身份令牌。


环境变量与敏感信息管理

环境变量基础

Vercel 的环境变量通过 Dashboard 或 CLI 配置,区分 Development(开发预览)、Preview(每个 PR 的预览环境)和 Production(生产环境)三个层级:

# 通过 CLI 设置
vercel env add DATABASE_URL
vercel env add OPENAI_API_KEY production
 
# 查看所有环境变量
vercel env ls
 
# 在本地使用生产环境变量进行调试
vercel env pull

类型安全的环境变量

使用 Zod 在构建时验证环境变量,避免运行时才发现配置错误:

// lib/env.ts
import { z } from "zod";
 
const envSchema = z.object({
  DATABASE_URL: z.string().url(),
  NEXTAUTH_SECRET: z.string().min(32),
  NEXTAUTH_URL: z.string().url().optional(),
  OPENAI_API_KEY: z.string().startsWith("sk-"),
  NEXT_PUBLIC_APP_URL: z.string().url(),
});
 
export const env = envSchema.parse(process.env);
 
type Env = z.infer<typeof envSchema>;
declare global {
  namespace NodeJS {
    interface ProcessEnv extends Env {}
  }
}

预览部署与团队协作

预览部署工作流

这是 Vercel 最让人印象深刻的特性之一。创建 Pull Request 后,Vercel 自动构建并部署到独立的预览环境,生成一个形如 https://feature-auth-k8s2xyz.vercel.app 的 URL。这个 URL 可以分享给任何人查看,不需要在本地运行项目。

合并到 main 分支后,Vercel 自动部署到生产环境。整个流程不需要任何手动操作。

在 Preview 环境配置密码保护

预览环境通常需要保护,避免搜索引擎索引和未授权访问。可以通过 Vercel CLI 为预览环境设置密码:

vercel deploy --token=xxx --password=mypassword

也可以通过中间件实现密码保护:

// middleware.ts
export function middleware(request: NextRequest) {
  const isPreview =
    request.url.includes(".vercel.app") ||
    process.env.NODE_ENV !== "production";
  const hasAuth = request.cookies.has("preview-auth");
 
  if (isPreview && !hasAuth) {
    const password = request.nextUrl.searchParams.get("password");
    if (password !== process.env.PREVIEW_PASSWORD) {
      return new NextResponse("<h1>Password Required</h1>", {
        headers: { "content-type": "text/html" },
      });
    }
 
    const response = NextResponse.next();
    response.cookies.set("preview-auth", "1", { maxAge: 3600 });
    return response;
  }
 
  return NextResponse.next();
}

Vercel 内置存储服务

Vercel KV(Redis 兼容)

Vercel KV 是基于 Upstash 的 Serverless Redis 服务,提供极快的键值读写能力:

import { Redis } from "@upstash/redis";
 
export const redis = new Redis({
  url: process.env.KV_REST_API_URL!,
  token: process.env.KV_REST_API_TOKEN!,
});
 
// 在 API Route 中使用
export async function GET(request: NextRequest) {
  const cached = await redis.get("data");
  if (cached) {
    return NextResponse.json({ source: "cache", data: cached });
  }
 
  const data = await fetchData();
  await redis.set("data", data, { ex: 3600 }); // 1小时过期
 
  return NextResponse.json({ source: "origin", data });
}

Vercel Blob(对象存储)

Vercel Blob 用于存储文件,提供流式上传、签名 URL 和自动 CDN 优化:

import { put } from "@vercel/blob";
 
export async function POST(request: NextRequest) {
  const formData = await request.formData();
  const file = formData.get("file") as File;
 
  if (!file) {
    return NextResponse.json({ error: "No file" }, { status: 400 });
  }
 
  const blob = await put(file.name, file, {
    access: "public",
  });
 
  return NextResponse.json({ url: blob.url });
}

Vercel Postgres(Serverless PostgreSQL)

Vercel Postgres 基于 Neon 技术,提供 Serverless 的 PostgreSQL 体验——不需要管理连接池,Vercel 帮你处理:

import { sql } from "@vercel/postgres";
 
export async function GET() {
  const { rows } = await sql`SELECT * FROM users LIMIT 10`;
  return NextResponse.json({ users: rows });
}

性能优化与缓存策略

ISR:增量静态再生成

ISR(Incremental Static Regeneration)是 Next.js 提供的介于 SSR 和 SSG 之间的渲染策略。页面在构建时预渲染为静态页面,但在过期后可以自动重新生成,而不需要重新部署:

// app/blog/[slug]/page.tsx
// 每小时重新验证一次
export const revalidate = 3600;
 
export default async function BlogPost({
  params,
}: {
  params: { slug: string };
}) {
  // 首次访问时执行,revalidate 秒后下次访问会重新执行
  const post = await fetchPost(params.slug);
 
  return (
    <article>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </article>
  );
}

这样一来,大部分访问走的是 CDN 缓存(极快),每隔一小时才有一个请求打到 Serverless Function 层,极大降低了成本。

缓存头配置

可以在 API Route 中手动设置缓存策略:

export async function GET() {
  const data = await getData();
 
  return NextResponse.json(data, {
    headers: {
      // CDN 缓存 1 小时,1 小时内即使数据更新也返回旧数据
      // stale 时允许后台重新验证
      "Cache-Control": "public, s-maxage=3600, stale-while-revalidate=86400",
    },
  });
}

定价体系

套餐对比

功能Hobby(免费)ProEnterprise
带宽100GB/月无限无限
Serverless Functions100 小时/月1000 小时/月自定义
Edge Functions500K 请求/月无限无限
预览部署
自定义域名1 个无限无限
密码保护预览
Analytics基础版高级版自定义
技术支持社区优先邮件专属客户成功
价格$0/月$20/月/人定制

成本优化建议

对于个人项目,免费版 Hobby 套餐基本够用:100GB 月带宽、100 小时 Serverless Functions、500K 次 Edge Function 请求,配合 ISR 缓存策略,大部分个人网站和小工具完全不用付费。

Pro 套餐适合团队协作场景——无限域名、密码保护预览、高级 Analytics 让 code review 和协作更高效。$20/月/人的定价在同类产品中属于中等偏上,但考虑到零运维成本和开发效率提升,性价比还是不错的。


与 Cloudflare Pages、Netlify 的对比

维度VercelCloudflare PagesNetlify
最佳场景Next.js 全栈应用边缘计算 + 免费存储静态站点 + Jamstack
Edge Network70+ 节点300+ 节点有限
ServerlessVercel FunctionsWorkersNetlify Functions
ISR 支持✓(独有)
图片优化内置需插件需插件
数据库Vercel PostgresD1(更丰富)第三方集成
对象存储Vercel BlobR2(免费存储!)Netlify Blobs
免费带宽100GB/月无限(CDN)100GB/月
学习曲线
Git 集成GitHub/GitLab/BitbucketGitHub/GitLabGitHub/GitLab

选择建议:如果你的项目使用 Next.js 并且需要全栈能力(SSR、API Routes、ISR),选 Vercel,它和 Next.js 的集成度无可替代。如果你想用最小的成本跑一个边缘应用,Cloudflare Pages + Workers + R2 的免费额度组合非常诱人。如果你的项目是纯静态站点并且追求简单配置,Netlify 是个好选择。


SUCCESS

Vercel 重新定义了前端部署的体验——不需要理解复杂的 CI/CD 配置,不需要管理服务器,不需要配置 CDN,只需要 push 代码,一切自动发生。对于追求效率的 vibecoding 开发者来说,Vercel 把部署的复杂性降到最低,让你真正把注意力放在代码本身。