关于 inngest-v3-v4-migration
inngest-v3-v4-migration 是用于将现有 Inngest 代码库从 v3 升级到 v4 的 Agent 技能,也可处理混用版本模式。它引导分阶段扫描用法、更新 API,并通过类型检查和针对性测试验证迁移。
主要功能
- 01扫描 Inngest 用法与 SDK 版本
- 02按顺序处理破坏性 API 变更
- 03迁移触发器与事件模式
- 04更新 realtime 和 step.invoke 用法
- 05通过类型检查与针对性测试验证
适用场景
- 01将项目从 Inngest v3 升级到 v4
- 02修复混用 v3 与 v4 API 的代码
- 03解决迁移相关的类型错误
- 04检查迁移后的运行时行为
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ inngest/ inngest-skills --skill inngest-v3-v4-migration安装后在 Claude Code 中输入/inngest-v3-v4-migration确认已加载。
详细介绍
Inngest v3 到 v4 迁移
当用户要求升级 Inngest、修复 v3/v4 错误、迁移实时功能,或清理包含混用 SDK 模式的代码库时,使用此技能。
主要参考: https://www.inngest.com/docs/reference/typescript/v4/migrations/v3-to-v4
此技能以 Agent 为先:先检测实际用法,再按受控顺序进行机械式 API 更改,随后进行类型检查并运行有针对性的测试。
触发条件
遇到以下请求时使用此技能:
- “将 Inngest 从 v3 升级到 v4”
- “修复我们的 Inngest v4 迁移”
- “升级后出现 signing key required / cloud mode 错误”
- “
step.invoke使用字符串函数 ID 已经不起作用” - “安装
inngest@4后,@inngest/realtime出问题了” - “从 EventSchemas 迁移到 eventType”
- “让这个现有的 Inngest 仓库兼容 v4”
如果用户要求先对整个代码库进行可靠性审计,请先使用
inngest-brownfield-audit 确定范围,然后回到此处进行 v4 更改。
迁移扫描
先定位所有 Inngest 相关位置:
rg -n '"inngest"|"@inngest/realtime"|"@inngest/agent-kit"' package.json **/package.json
rg -n 'new Inngest|EventSchemas|eventType|staticSchema|createFunction\\(|serve\\(|connect\\(|step\\.invoke|referenceFunction|@inngest/realtime|realtimeMiddleware|useInngestSubscription|serveHost|rewriteGatewayEndpoint|logLevel|streaming:|signingKey|signingKeyFallback|baseUrl|INNGEST_DEV|INNGEST_SIGNING_KEY' .
然后对仓库进行分类:
- **尚未使用 Inngest:**使用
inngest-setup,而非此迁移技能。 - **仅使用 v3:**同时迁移 SDK 和所有破坏性更改。
- **混用 v3/v4:**优先从 v4 代码中移除已失效的 v3 API。
- **基本完成 v4 迁移:**重点检查遗漏的运行时注意事项,例如本地开发模式、无服务器
maxRuntime、realtime 软件包导入,以及字符串step.invoke。
编辑前,记录:
Inngest migration scan:
- Current package versions:
- Client files:
- Serve/connect entrypoints:
- Functions using old trigger syntax:
- EventSchemas usage:
- Realtime v3 package usage:
- step.invoke string IDs:
- Serverless runtime constraints:
- Tests/checks available:
升级顺序
- 更新软件包版本。
- 修复客户端构造方式以及本地/生产模式。
- 将 serve 选项移至客户端。
- 将触发器移入
createFunction选项。 - 将
EventSchemas替换为eventType()/staticSchema()。 - 重写
step.invoke()字符串 ID。 - 将 realtime 从
@inngest/realtime迁移到 v4 原生 API。 - 更新中间件和日志记录。
- 配置 checkpointing/无服务器运行时。
- 进行类型检查、运行测试,并可选择与开发服务器同步。
软件包和环境
安装最新的 v4 SDK:
npm install inngest@latest
# or pnpm add inngest@latest
# or yarn add inngest@latest
如果仓库使用 v3 realtime,请移除 @inngest/realtime;v4 realtime 位于
inngest 软件包中,包括 inngest/realtime、inngest/react 等子路径,以及原生的 step.realtime / inngest.realtime。
v4 默认使用 Cloud 模式。进行本地开发时,请使用环境变量:
INNGEST_DEV=1 npm run dev
除非仓库现有的环境模式明确限定为仅在本地使用,否则不要在源代码中硬编码 isDev: true。生产环境应使用
INNGEST_SIGNING_KEY。
客户端和 Serve 选项
在 v4 中,signingKey、signingKeyFallback 和 baseUrl 等选项应传入
new Inngest(...),而非 serve(...)。
// Old v3
app.use(
"/api/inngest",
serve({
client: inngest,
functions,
signingKey: process.env.INNGEST_SIGNING_KEY,
baseUrl: process.env.INNGEST_BASE_URL,
})
);
// New v4
export const inngest = new Inngest({
id: "my-app",
signingKey: process.env.INNGEST_SIGNING_KEY,
baseUrl: process.env.INNGEST_BASE_URL,
});
app.use("/api/inngest", serve({ client: inngest, functions }));
如果仓库已经依赖受支持的环境变量,且未显式传入 serve 选项,则这些密钥可能无需更改代码。
其他重命名:
serveHost->serveOriginstreaming: "force"->streaming: truestreaming: "allow"->streaming: truestreaming: false保持为falselogLevel已移除;请传入logger,例如new ConsoleLogger({ level })
createFunction 触发器
触发器移入第一个参数的选项对象中。
// Old v3
inngest.createFunction(
{ id: "send-welcome" },
{ event: "user/created" },
async ({ event, step }) => {}
);
// New v4
inngest.createFunction(
{ id: "send-welcome", triggers: [{ event: "user/created" }] },
async ({ event, step }) => {}
);
Cron 触发器也以相同方式迁移:
inngest.createFunction(
{ id: "nightly-sync", triggers: [{ cron: "0 2 * * *" }] },
async ({ step }) => {}
);
如果某个函数仅通过 step.invoke 调用,则它可以不设置触发器。
从 EventSchemas 迁移到 eventType/staticSchema
将集中式的 EventSchemas 替换为特定事件的定义。
import { Inngest, eventType, staticSchema } from "inngest";
import { z } from "zod";
export const userCreated = eventType("user/created", {
schema: z.object({
userId: z.string(),
email: z.string().email(),
}),
});
type InvoicePaid = {
invoiceId: string;
customerId: string;
};
export const invoicePaid = eventType("billing/invoice.paid", {
schema: staticSchema<InvoicePaid>(),
});
统一使用事件类型:
await inngest.send(userCreated.create({ userId, email }));
inngest.createFunction(
{ id: "on-user-created", triggers: [userCreated] },
async ({ event }) => {}
);
await step.waitForEvent("wait-for-invoice", {
event: invoicePaid,
timeout: "7d",
});
请注意:staticSchema 接受的是类型,而非接口。必要时,将接口转换为类型别名。
step.invoke
v4 不再接受原始字符串形式的函数 ID。请使用导入的函数引用或
referenceFunction()。
import { referenceFunction } from "inngest";
await step.invoke("run-report", {
function: referenceFunction({
appId: "analytics-app",
functionId: "generate-report",
}),
data: { reportId },
});
如果目标函数位于同一代码库中,优先直接传入导入的函数:
await step.invoke("run-report", {
function: generateReport,
data: { reportId },
});
实时功能迁移
v3 实时功能使用了 @inngest/realtime 和由中间件注入的 publish。
v4 实时功能是原生功能。
替换:
@inngest/realtime包realtimeMiddleware(){ publish }等处理程序参数useInngestSubscription()等 v3 React hooks
改用:
inngest/realtime中的通道定义- 步骤之间的
step.realtime.publish - 在现有
step.run内使用inngest.realtime.publish - 当前 v4 API 中的订阅辅助函数/hooks
详细模式请参阅 inngest-realtime。不要在 step.run 内调用
step.realtime.publish;应在其中使用 inngest.realtime.publish
以避免步骤嵌套行为。
并行处理和检查点
v4 默认启用优化并行处理和检查点。
留意对步骤使用 Promise.race 的情况。在优化并行处理下,Promise.race
会等待所有步骤 Promise 都完成。如果仓库依赖先完成者胜出的行为,请使用
group.parallel()。
对于无服务器平台,请将检查点的 maxRuntime 配置为略低于平台限制:
export const inngest = new Inngest({
id: "my-app",
checkpointing: {
maxRuntime: "50s",
},
});
在 Vercel 或类似框架上,如果平台支持,还要设置路由处理程序的最长持续时间。
Connect 变更
如果仓库使用 Connect:
rewriteGatewayEndpoint已替换为gatewayUrl。- Connect 可能使用工作线程隔离。如果出现集成问题,请检查
isolateExecution: false或INNGEST_CONNECT_ISOLATE_EXECUTION=false。 - 将目标 URL 和签名/事件密钥保存在环境变量中。
验证
按置信度从低到高运行检查:
- 安装/更新包管理器依赖。
- 类型检查。
- 迁移函数相关的单元/集成测试。
- 使用
INNGEST_DEV=1启动应用。 - 运行
npx inngest-cli@latest dev并确认函数发现正常。 - 发送一个有代表性的事件并检查运行情况。
如果无法通过本地开发服务器进行验证,请明确说明哪些静态检查已通过,以及还需要进行哪些运行时验证。
常见错误消息
- "A signing key is required to run in Cloud mode":本地开发时设置
INNGEST_DEV=1,或为生产环境配置INNGEST_SIGNING_KEY。 - 在
/api/inngest上出现Cls is not a constructor:可能是在 v4 应用中使用了 v3@inngest/realtime中间件。移除该包并迁移到原生实时功能。 step.invoke使用字符串函数 ID 时失败:将字符串替换为导入的函数引用或referenceFunction()。- 与 schema 相关的类型错误:将
EventSchemas替换为eventType()和staticSchema()。 Promise.race行为异常:对于先完成者胜出的步骤竞速,请使用group.parallel();仅在必要时禁用优化并行处理。
反模式
- 将 v3 实时中间件与
inngest@4混用。 - 向
serve()传递signingKey、baseUrl或signingKeyFallback。 - 迁移事件触发器语法,却忘了 cron/调用触发的函数。
- 将
EventSchemas全部替换为无类型的字符串事件。 - 在面向生产环境的源代码中硬编码
isDev: true。 - 在
step.invoke中遗留字符串 ID。 - 机械迁移后跳过类型检查。