Mastra 部署到 Vercel 实战指南:@mastra/deployer-vercel 部署器原理与使用全解析
【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra
@mastra/deployer-vercel 是 Mastra 框架的官方 Vercel 部署器,负责将你的 Mastra 服务器打包并生成符合 Vercel Build Output API 规范的产物,包括 serverless 函数、静态资源与路由表。本文基于该包的 CHANGELOG.md 版本演进记录,结合包内源码、类型定义与测试用例,系统讲解其安装配置、Studio 静态部署模式、自定义 API 路由路由表修复、函数打包参数(.vc-config.json)、externals 强制策略,以及版本演进中值得关注的兼容性边界,帮助你理解"从 Mastra 应用到 Vercel 线上函数"的完整链路,并能在实际项目中正确使用与排查问题。
一、包概览与安装
@mastra/deployer-vercel在 Mastra 中扮演"Vercel 专属部署适配层"的角色:它继承自@mastra/deployer的Deployer基类,实现prepare、bundle、deploy、lint等方法,最终把 Mastra 应用转换为 Vercel 可识别的输出目录结构(.vercel/output/...)。
在 package.json 中可以确认以下事实:
- 运行时要求:
engines.node为>=22.13.0,与 1.0.0 版本记录中"Bump minimum required Node.js version to 22.13.0"的变更一致; - peer 依赖:
@mastra/core要求>=1.50.0-0 <2.0.0-0。CHANGELOG 中大量条目(如 1.1.31、1.1.27、0.10.0 的 "Move @mastra/core to peerdeps")都在持续抬高或修正这一 peer 依赖下限,安装时需确保核心包版本与之匹配; - 运行时依赖:仅
@mastra/deployer与fs-extra(用于文件复制与移动); - license:Apache-2.0(早期版本曾短暂切换过 Elastic-2.0,见 0.1.18 条目,当前版本为 Apache-2.0)。
安装方式(见 README.md):
npm install @mastra/deployer-vercel二、基础用法与配置参数
在 Mastra 应用中,部署器通过Mastra实例的deployer字段接入:
import { Mastra } from '@mastra/core/mastra'; import { VercelDeployer } from '@mastra/deployer-vercel'; const deployer = new VercelDeployer({ // 可选:按函数维度覆盖,会写入 .vc-config.json maxDuration: 600, memory: 1536, regions: ['sfo1', 'iad1'], }); const mastra = new Mastra({ deployer, // ... 其他 Mastra 配置 });配置参数说明
VercelDeployerOptions的定义位于 types.ts,完整参数如下:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
studio | boolean | false | 是否随 API 一起部署 Mastra Studio(静态资源模式,见下一节) |
maxDuration | number | 未设置 | 函数最大执行时长(秒),覆盖写入.vc-config.json的maxDuration |
memory | number | 未设置 | 函数内存上限(MB),覆盖写入.vc-config.json的memory |
regions | string[] | 未设置 | 函数部署区域,如['sfo1', 'iad1'],写入.vc-config.json的regions |
从 index.ts 的实现可以看到,构造函数会把除studio之外的字段整体收集为vcConfigOverrides,在bundle()阶段与默认配置合并:
constructor(options: VercelDeployerOptions = {}) { super({ name: 'VERCEL' }); this.outputDir = join('.vercel', 'output', 'functions', 'index.func'); this.studio = options.studio ?? false; const { studio, ...overrides } = options; this.vcConfigOverrides = { ...overrides }; }默认函数配置(.vc-config.json)
bundle()中生成的VcConfig默认值(字段见 types.ts):
const vcConfig: VcConfig = { handler: 'index.mjs', launcherType: 'Nodejs', runtime: `nodejs${nodeVersion}.x`, // 依据当前 Node 主版本号生成,如 nodejs22.x shouldAddHelpers: true, }; // 合并覆盖项 if (typeof maxDuration === 'number') vcConfig.maxDuration = maxDuration; if (typeof memory === 'number') vcConfig.memory = memory; if (Array.isArray(regions) && regions.length > 0) vcConfig.regions = regions;值得说明的是,CHANGELOG 中0.12.5条目正是"add params for vc-config.json"(为.vc-config.json增加参数能力)的引入点;而0.11.0与0.10.6两条记录分别对应"修复 CLI 与 Git 集成的部署体验"与"改用 Build Output API 修复 CLI/Git 部署",共同构成了当前基于 Vercel Build Output API(输出目录 +config.json路由表 +.vc-config.json函数配置)的部署模型。
三、Studio 静态部署模式(studio: true)
CHANGELOG1.1.0的 Minor 变更引入了最重要的功能选项 ——studio:
Added
studiooption to deploy Studio alongside your API. When enabled, Studio is served as static assets from Vercel's Edge CDN while the API stays in the serverless function. No function invocations are consumed for Studio requests. (#13532)
import { VercelDeployer } from '@mastra/deployer-vercel'; new VercelDeployer({ studio: true, });其运行机制(结合 index.ts 的prepare()实现)为:
- 从包的
dist/studio读取 Studio 构建产物,连同routes-manifest.json(Studio 顶层路由段清单)一起读取; - 将 Studio 静态资源复制到
.vercel/output/static目录 —— 这些资源由 Vercel Edge CDN 直接提供,不触发任何函数调用; - 通过
injectStudioConfig()把运行期配置注入index.html; - 生成版本 3 的
config.json路由表(见writeVercelJSON():JSON.stringify({ version: 3, routes: getVercelRoutes(...) }))。
Studio 路由表与自定义 API 路由修复(1.2.13)
studio: true场景下最关键的修复是1.2.13:
Fixed custom API routes being unreachable when deploying to Vercel with
studio: true. (#20517)
问题背景:通过registerApiRoute()注册的自定义路由挂载在服务器根路径,而早期生成的路由表只把/api/*与/health转发给你的应用,其余路径全部落入 Studio 的index.html—— 于是请求自定义路由会拿到 Studio 的 HTML 页面,处理器从未执行。又不能把这些路由搬到/api前缀下,因为该前缀预留给内置路由。
修复后的路由表(见 routes.ts)改为:Studio 拥有路径由 CDN 直接服务,其余一切路径交给服务器函数:
export function getVercelRoutes({ studio, studioRouteRoots = [] }: VercelRoutesOptions) { if (!studio) { return [{ src: '/(.*)', dest: '/' }]; } const spaRoots = studioRouteRoots.map(escapeRegExp).join('|'); return [ { src: '^/$', dest: '/index.html' }, ...(spaRoots ? [{ src: `^/(?:${spaRoots})(?:/.*)?$`, dest: '/index.html' }] : []), { handle: 'filesystem' as const }, { src: '/(.*)', dest: '/' }, ]; }核心语义是:
^/$与 Studio 顶层 SPA 路径(来自routes-manifest.json)先命中静态index.html;handle: filesystem之前的路由优先匹配,之后的路由仅在静态文件系统 miss 时生效;- 兜底
/(.*)全部指向函数,因此自定义路由(即使不在/api下)也能到达服务器;同时自定义server.apiPrefix的请求同样会被转发(CHANGELOG 1.2.13 明确说明这一点),但 Studio 自身 UI 仍固定调用/api,因此为 Studio 指向自定义前缀尚不受支持。
CHANGELOG 给出的验证示例:
export const mastra = new Mastra({ deployer: new VercelDeployer({ studio: true }), server: { apiRoutes: [registerApiRoute('/my/webhook', { method: 'POST', handler: c => c.json({ ok: true }) })], }, });修复后POST /my/webhook返回{"ok":true}而非 Studio 的index.html。
路由表测试 routes.test.ts 用 8 个用例固化了这些行为,包括:Studio 根路径与 SPA 路径(/agents、/agents/weather-agent/chat、/agent-builder、/workflows)命中静态index.html;自定义路由(/my/webhook、/inngest/api、/chat)与内置端点(/api/agents、/health)命中函数;非默认apiPrefix(/mastra/agents)命中函数;静态资源(/assets/...js、/mastra.svg)留给 filesystem;SPA 路由段中的正则特殊字符(如a.b)被正确转义。
Studio HTML 配置注入与转义(1.2.5)
1.2.5修复了 Studio HTML 配置注入的安全问题:
Fixed Studio HTML config injection so platform environment values are escaped before they are embedded in served or deployed
index.htmlfiles. ... and exposesescapeStudioHtmlValuefrom@mastra/deployer/buildfor the shared injection paths. (#18812)
含义是:组织 ID、项目 ID、可观测性端点、遥测开关等平台环境变量在嵌入index.html前必须转义,否则值中若含引号、尖括号、换行或$序列会破坏 HTML。源码中的injectStudioConfig()展示了这一套注入逻辑,同时1.1.8条目(注入MASTRA_EXPERIMENTAL_UI)与1.1.9(Studio 浅色模式)也都在此链路内演进。
1.2.4进一步为 Studio 的信号(Signals)页面暴露了MASTRA_ORGANIZATION_ID、MASTRA_PLATFORM_PROJECT_ID、MASTRA_PLATFORM_OBSERVABILITY_ENDPOINT,并指出该路由受平台可观测性配置门控、MASTRA_SIGNALS_UI控制侧边栏入口;这些变量的注入逻辑可以在injectStudioConfig()的injectStudioHtmlConfig(...)调用中逐一看到对应位置。
四、打包链路:入口生成、externals 与函数导出
生成的 Vercel 入口(getEntry)
getEntry()生成实际进入 Vercel 函数的模块:基于 Hono 的handle,从#mastra、#server、#tools三个虚拟模块组装服务器,并按 HTTP 方法导出:
export const GET = handle(app); export const POST = handle(app); export const PUT = handle(app); export const DELETE = handle(app); export const PATCH = handle(app); export const OPTIONS = handle(app); export const HEAD = handle(app);从 CHANGELOG 可以看到这组导出的演进:0.10.0修复了 PUT/DELETE 请求("Fixed PUT/DELETE reqeusts for Vercel deployer"),0.11.21增加了PATCH方法支持,当前版本已覆盖全部 7 种 HTTP 方法。入口同时注册了scoreTracesWorkflow内部工作流(当应用配置了 storage 时),用于 trace 评分批处理(对应0.12.2的 "implement trace scoring with batch processing capabilities")。
bundle 接口变更(0.12.0)
CHANGELOG0.12.0记录了IBundler/IDeployer接口的破坏性变更 ——bundle()第三个参数由数组改为对象:
- bundle(entryFile: string, outputDirectory: string, toolsPaths: (string | string[])[]): Promise<void>; + bundle(entryFile: string, outputDirectory: string, options: { toolsPaths: (string | string[])[]; projectRoot: string }): Promise<void>;并明确说明:如果你只是在src/mastra/index.ts中使用部署器,升级无需任何改动;只有直接调用bundle()的第三方扩展者需要适配。当前源码中的bundle()签名即为此新形态。
强制 externals: true(1.1.10)
1.1.10修复了 Vercel 部署器缺失的 ESM 兼容性策略:
fix(deployer-vercel): always force externals: true to prevent ESM TLA deadlocks (#14863)
Cloud 部署器与 CLImastra build早已强制externals: true以避免动态导入产生代码分割 chunk 时的循环模块求值死锁,而 Vercel 部署器当时遗漏了该修复。源码中getUserBundlerOptions()对此有明确注释与实现:
// Always force externals: true for Vercel deployments. // Vercel serverless functions resolve dependencies from node_modules, // so bundling them inline serves no purpose. Bundling inline can also cause // circular module evaluation deadlocks when dynamic imports produce chunks // that depend back on the entry module via static imports, resulting in // "Detected unsettled top-level await" errors (Node.js exit code 13). return { ...bundlerOptions, externals: true, };这也意味着 Vercel 场景下依赖统一从node_modules解析、不内联打包 —— 部署时需确保相关依赖可安装。
lint 内置约束:libsql 不支持
lint()会检查依赖中是否包含@mastra/libsql:Vercel Deployer 不支持@libsql/client(可能由@mastra/libsql间接引入),发现时会输出错误并退出进程,建议改用@mastra/pg等其他存储方案。
deploy() 的现状
deploy()目前仅输出提示:
async deploy(): Promise<void> { this.logger?.info('Deploying to Vercel is deprecated. Please use the Vercel dashboard to deploy.'); }即程序化部署已废弃,推荐通过 Vercel 控制台 / Git 集成完成部署(对应 CHANGELOG 0.11.0 对 CLI 与 Git 集成体验的修复)。
五、版本演进要点与升级注意事项
从 CHANGELOG 可以梳理出几条对使用者有实际影响的演进主线:
- 1.0.0 稳定版:标记为 stable,同时引入多项破坏性变更 —— 最低 Node.js 版本提升到 22.13.0、scorers 迁移到 eval 域并强制要求 id、移除 legacy evals、
@mastra/corepeer 依赖与核心版本对齐到 1.0.0。1.0.0-beta.2还加入了嵌入式文档支持(npm 包内dist/docs/下的 SKILL.md、SOURCE_MAP.json、主题文件夹)。 - AgentController 命名(1.2.2):
Harness类及Harness*类型重命名为AgentController/AgentController*,@mastra/core/agent-controller成为规范入口,旧/harness/...路由与harness:*权限被移除;@mastra/deployer-vercel等部署器、服务器适配器、@mastra/temporal均被连带提升 peer 依赖下限(>=1.47.0-0)。使用托管式 agent 控制台的用户需按新命名迁移。 - Agent Signals 流式路径(1.1.28 / 1.1.33):Studio/playground 聊天运行时可通过
MASTRA_AGENT_SIGNALS环境变量切换到sendSignal+subscribeToThread流式路径;默认(未设置)回退到streamUntilIdle路由;enableThreadSignals: false与显式 legacy Stream 仍是退出开关。React 的useChat()对 SDK 消费者则通过enableThreadSignals: true显式开启。 - 供应链与发布治理:
1.1.40针对 2026-06-17 "easy-day-js" 供应链事件做了补丁发布;1.2.23将CHANGELOG.md从 npm 分发文件中移除以减小包体积,并更新 README 保证信息准确;0.11.19完善了package.json的repository、homepage、files字段;0.12.9将@rollup/*依赖固定到精确版本以规避上游热修复与夜间破坏。 - includeFiles 与函数体积(0.1.20 / 0.1.21):早期版本围绕
vercel.json的includedFiles数组做过"遍历目录收集全部文件"与"优化 includeFiles 模式以降低函数上限"两轮修复,这些沉淀为当前 Build Output API 输出模型的一部分。
六、深入阅读路径
如果你希望进一步验证本文涉及的行为,可以直接查看以下文件:
- 部署器核心实现:
VercelDeployer类完整代码,覆盖构造、prepare、getEntry、bundle、lint、Studio 注入; - 路由表生成:
getVercelRoutes(),理解 Studio 与函数之间的路径裁决规则; - 路由表测试:8 组用例覆盖根路径、SPA 路由、自定义路由、内置端点、自定义 apiPrefix、静态资源与正则转义;
- 类型定义:
VcConfig、VcConfigOverrides、VercelDeployerOptions; - 包元信息:版本、engines、peer 依赖与脚本;
- 版本演进全记录:按版本号回溯每个行为变更的来龙去脉与对应 PR。
综上所述,@mastra/deployer-vercel通过"Build Output API 输出 + Hono 多方法导出 + 静态 Studio + 精确路由表"的组合,让 Mastra 应用能以极低的函数调用成本运行在 Vercel 上。理解studio: true下的路由裁决规则(自定义路由必须回落到函数)、.vc-config.json的可覆盖参数,以及 Node 22.13.0 与 peer 依赖的版本边界,是避免"线上路由被 Studio 吞掉"、"函数配置不生效"等典型问题、顺利完成生产部署的关键。
【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考