关于 integrating-convex-expo
integrating-convex-expo 是一项技能,用于在 Expo 和 React Native 应用中添加、修复或扩展 Convex 后端。内容涵盖环境与 Provider 配置、功能开发、验证和发布加固。
主要功能
- 01配置 Convex 客户端与 Provider
- 02设置环境变量和 EAS
- 03构建 Schema、函数及前端 Hooks
- 04实现身份验证和文件上传
- 05验证并加固集成
适用场景
- 01将 Convex 接入 Expo 应用
- 02跨后端与应用实现功能
- 03修复 Provider、环境或生成 API 问题
- 04为发布准备集成
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ tristanmanchester/ agent-skills --skill integrating-convex-expo安装后在 Claude Code 中输入/integrating-convex-expo确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/evals.jsontrigger-queries.jsonreferences/auth.mdcomponents-and-helpers.mdeas-env.mdevaluation.mdfile-uploads.mdfrontend-patterns.mdfunctions.mdmigrations.mdproduction-checklist.mdschema-and-indexes.mdsources.mdtasks-example.mdtroubleshooting.mdscripts/scaffold_tasks_example.pyvalidate_project.py详细介绍
将 Convex 集成到 Expo(React Native)
使用此技能为 Expo 应用添加、修复、扩展或加固 Convex 后端,同时避免偏离到仅适用于 Web 的模式或泛泛的 React Native 建议。
适用场景
- 将 Convex 添加到现有的 Expo 或 Expo Router 应用中。
- 修复有问题的环境配置、提供程序接线或生成的 API 导入。
- 构建端到端的功能切片:架构、索引、后端函数、前端钩子和验证。
- 为 Expo + Convex 选择并实现身份验证。
- 将文件从 Expo URI 上传到 Convex 存储。
- 为分页、索引、迁移或可复用组件进行重构。
- 在预览版或生产版发布前加固项目。
不适用场景
- 不涉及 Convex 的纯 Expo UI、动画、导航或样式工作。
- 前端不是 Expo 或 React Native 的 Convex 项目。
- 不需要 Expo 专属环境或客户端接线的通用后端架构讨论。
成功标准
良好的结果应使项目具备:
- 一个范围设置正确的 Convex 客户端和提供程序。
EXPO_PUBLIC_CONVEX_URL在本地开发和 EAS 中均能正常使用。- 后端函数符合 Convex 关于验证器、身份验证、操作和查询性能的最佳实践。
- 前端钩子使用生成的
api引用,并清晰处理加载、空数据和错误状态。 - 使用
scripts/validate_project.py完成验证。 - 为后续扩展提供清晰路径:分页、索引、身份验证包装器、迁移和 lint。
不可妥协的要求
- 开发或修复集成时,保持
npx convex dev运行。 - 从
process.env.EXPO_PUBLIC_CONVEX_URL读取部署 URL。 - 在 EAS 环境中镜像此值,以用于预览版和生产版构建。
- 每个应用仅创建一个
ConvexReactClient,并将其放在渲染路径之外。 - 在真正的根入口挂载提供程序:
app/_layout.tsx、src/app/_layout.tsx或App.tsx。 - 在 Expo 和 React Native 中,设置
unsavedChangesWarning: false。 - 从
convex/_generated/api导入生成的引用,不要使用依赖字符串的名称。 - 将所有客户端可调用的 Convex 函数视为不可信入口。
- 为公共函数添加
args验证器,并且也尽量使用returns验证器。 - 保持公共包装器精简;将重复逻辑移至辅助函数、内部函数或自定义包装器。
- 不要在查询逻辑中使用
Date.now()或new Date()。 - 不要在查询或变更中使用仅限 Node.js 的 API 或第三方 SDK。
- 将外部 API 调用、繁重计算或仅限 Node.js 的库放入
action或internalAction文件;如果文件以"use node"开头,则只放置操作。 - 避免在大型表上使用
.filter()和无界的.collect();优先使用索引和分页。 - 等待每一个 Promise 完成。
- 优先使用 TypeScript 严格模式和官方 Convex ESLint 插件。
首轮排查
进行更改前,先检查项目并确定任务类别。
1. 确认应用入口点
检查以下文件:
- Expo Router 项目的
app/_layout.tsx或src/app/_layout.tsx。 - 传统入口项目的
App.tsx或App.jsx。
2. 审查 Convex 状态
检查以下内容:
package.json依赖项:convex、expo、身份验证库、ESLint 工具。convex/和convex/_generated/。.env.local、.env、.env.development、.env.production。- 如果涉及云构建,检查
eas.json。 - 现有的提供程序用法:
ConvexProvider、ConvexProviderWithClerk或自定义身份验证包装器。 convex/schema.ts中现有的架构和索引。- 缺少验证器、身份验证检查或分页的现有公共函数。
3. 运行验证器
在项目根目录运行:
python scripts/validate_project.py --root <project-root>
需要机器可读的输出时使用 --json;需要更严格的门禁时使用 --fail-on-warning。
4. 选择工作流
- 初始化 / 修复基线:缺少 Convex 设置、环境变量、提供程序或生成的 API。
- 构建功能切片:同时添加后端数据和 UI。
- 身份验证:添加或修复登录和后端授权。
- 文件上传:将媒体或文档从设备 URI 移至 Convex 存储。
- 扩展 / 加固:索引、分页、组件、Lint 检查、生产环境检查清单。
- 迁移:重塑现有表,或逐步从其他后端迁移。
工作流 A — 初始化或修复基线集成
步骤 1:安装或确认客户端包
npx expo install convex
步骤 2:创建或重新连接 Convex 项目
npx convex dev
此操作会:
- 创建或连接 Convex 项目,
- 在缺失时创建
convex/, - 生成
convex/_generated/, - 将
EXPO_PUBLIC_CONVEX_URL写入.env.local, - 并在命令运行期间持续同步。
步骤 3:确保根提供程序存在
对于 Expo Router:
import { ConvexProvider, ConvexReactClient } from "convex/react";
import { Stack } from "expo-router";
const convex = new ConvexReactClient(process.env.EXPO_PUBLIC_CONVEX_URL!, {
unsavedChangesWarning: false,
});
export default function RootLayout() {
return (
<ConvexProvider client={convex}>
<Stack />
</ConvexProvider>
);
}
对于经典的 App.tsx,以相同方式包装顶层导航树。
步骤 4:确认生成的导入
使用:
import { api } from "../convex/_generated/api";
或根据项目布局使用正确的相对路径。不要手动编写函数名称。
步骤 5:验证开发和构建环境
阅读 references/eas-env.md,并确保 EAS 采用相同的部署 URL 策略。
步骤 6:验证并进行冒烟测试
- 启动 Expo 应用。
- 确认
useQuery(...)从undefined变为真实数据。 - 运行
python scripts/validate_project.py --root <project-root>。 - 如有需要,使用
python scripts/scaffold_tasks_example.py --root <project-root>搭建规范示例。
工作流 B — 端到端构建功能切片
按以下顺序构建每项功能。
1. 首先对访问模式建模
开始编写代码前,回答以下问题:
- 数据是公开的、限定用户的、限定组织的,还是仅限管理员访问?
- 列表会保持较小规模,还是应进行分页?
- 哪些字段是查找键,因此需要索引?
- 是否有步骤需要外部 API、AI SDK、Stripe 或 Node API?
2. 设计架构
当数据模型趋于稳定时,先添加或扩展 convex/schema.ts,再编写函数层。
请参阅 references/schema-and-indexes.md,了解:
- 扁平关系建模,
- 外键索引,
- 基于实际查询模式的复合索引,
- 有界数组指南,
- 以及分页阈值。
3. 实现后端函数
详细模式请参阅 references/functions.md。
默认规则:
- 对确定性读取使用
query。 - 对写入使用
mutation。 - 对外部 API、第三方 SDK 或仅限 Node 的代码使用
action或internalAction。 - 对不应由客户端调用的逻辑使用
internalQuery或internalMutation。
4. 在后端强制执行访问控制
如果功能不是公开的,请采用以下方式之一:
- 在每个函数中显式检查
ctx.auth.getUserIdentity(),或 - 通过
convex-helpers使用可复用的自定义包装器。
请参阅 references/auth.md 和 references/components-and-helpers.md。
5. 接入前端
请参阅 references/frontend-patterns.md。
务必处理:
- 加载状态:
useQuery(...) === undefined, - 空状态,
- 相关情况下的 mutation 等待状态,
- 可恢复的错误,
- 以及无界列表的分页。
6. 验证功能切片
完成前:
- 使用项目根目录运行验证器,
- 如果项目配置了 Lint 和类型检查,请运行它们,
- 在设备或模拟器上验证功能,
- 并在发布前更新或添加索引。
工作流 C — 身份验证和授权
选择一种身份验证方案,并确保技术栈保持一致。
选项 1:Clerk
适用于已使用 Clerk 或希望采用完善身份验证产品的应用。
选项 2:Convex Auth
适用于希望使用 Convex 原生身份验证技术栈,并愿意采用 Beta 库的情况。
选项 3:现有 JWT 或 OIDC 提供方
适用于产品已依赖 Auth0、WorkOS、公司 IdP 或其他 OIDC 流程的情况。
无论使用哪种提供方,都应遵守以下规则
- 后端授权是强制要求;客户端限制访问仅用于改善用户体验。
- 如果在 Convex 中持久化用户,请使用
tokenIdentifier等稳定标识符建立索引。 - 对每个受保护函数,都要检查所有权、组织成员资格或角色。
- 尽量使用辅助函数或自定义封装,避免重复编写身份验证样板代码。
- 对特权内部操作使用内部函数。
请阅读 references/auth.md,了解决策矩阵和实现模式。
工作流 D — 从 Expo 上传文件
使用 Convex 上传 URL,而不是尝试通过 mutation 传送原始文件。
推荐流程:
- 公共或受保护的 mutation 返回
ctx.storage.generateUploadUrl(), - 客户端使用
fetch(uri)加载本地file://URI,并将其转换为Blob, - 客户端将该 blob
POST到上传 URL, - 第二个 mutation 保存返回的
storageId以及应用专属的元数据, - 可选的后处理在之后通过计划任务或 action 执行。
请阅读 references/file-uploads.md。
工作流 E — 扩展和强化
基线功能正常后,提高质量标准。
性能
- 尽可能将
.filter()扫描替换为索引查询。 - 将不受限的
.collect()替换为take、first或分页查询。 - 对不断增长的信息流、通知和无限滚动页面使用
usePaginatedQuery。 - 当边界明确时,将重复或可复用的功能区域移至 Convex 组件。
安全性
- 始终添加验证器。
- 将特权逻辑置于内部函数之后。
- 对预期的失败使用
ConvexError或清晰的返回结构。 - 未检查所有权或成员资格前,切勿信任来自客户端的 ID。
可维护性
- 启用
@convex-dev/eslint-plugin。 - 使用 TypeScript 严格模式。
- 保持封装精简,并将共享逻辑移至纯 TypeScript 辅助函数。
- 将
"use node"action 文件与常规运行时文件分开。
请阅读 references/production-checklist.md。
工作流 F — 迁移
更改线上 schema 时,优先采用增量式过渡。
默认迁移策略:
- 以向后兼容的方式添加新字段或表,
- 如果数据结构发生变化,则同时读取或同时写入,
- 以幂等批次回填现有文档,
- 切换读取端和写入端,
- 然后移除旧结构。
使用内部函数或计划任务进行回填,并确保迁移可以安全重启。
快速故障排查流程
如果应用出现故障,请按顺序检查:
npx convex dev是否正在运行,且没有 TypeScript 错误?.env.local是否包含EXPO_PUBLIC_CONVEX_URL?- 环境文件更改后是否重启了 Metro?
- 是否恰好只有一个
ConvexReactClient? - Provider 是否挂载在真正的根节点?
convex/_generated/api是否存在,导入路径是否正确指向它?- 公共函数是否缺少
args或returns验证器? - 查询是否使用了
Date.now()、.filter()或不受限的.collect()? "use node"文件是否错误地混用了查询或 mutation?- 客户端 Provider 与后端配置中的身份验证是否不匹配?
请参阅 references/troubleshooting.md。
可用脚本
-
scripts/validate_project.py- 验证以
--root指定的项目;如果该脚本被复制到仓库中,则验证当前工作树。 - 验证 Expo 和 Convex 依赖项。
- 检查环境文件、提供方接线、生成的代码、验证器是否存在、误用
"use node"的情况,以及常见的查询反模式。 - 支持
--json、--root和--fail-on-warning。
- 验证以
-
scripts/scaffold_tasks_example.py- 默认进行试运行。
- 可以生成
sampleData.jsonl、convex/schema.ts、convex/tasks.ts,以及可选的 Expo 屏幕文件。 - 支持
--write、--overwrite、--ui-file和--json。
参考资料
仅加载与当前任务对应的文件。
- references/eas-env.md — 本地环境、EAS 环境和部署 URL 处理。
- references/tasks-example.md — 该技术栈的规范最简示例。
- references/schema-and-indexes.md — 模式设计、索引、查询形状映射和分页触发条件。
- references/functions.md — 查询、变更、操作、内部函数、验证器和运行时边界。
- references/frontend-patterns.md — 提供方放置位置、钩子用法、加载和错误状态,以及分页列表。
- references/auth.md — Clerk、Convex Auth、JWT 或 OIDC、用户映射和服务端授权。
- references/file-uploads.md — 上传 URL、Expo URI 处理、元数据存储和后处理。
- references/components-and-helpers.md — Convex 组件和
convex-helpers模式。 - references/migrations.md — 增量式发布、回填、双重读写和分批迁移。
- references/production-checklist.md — 发布前加固检查清单。
- references/troubleshooting.md — 常见故障及其具体修复方法。
- references/evaluation.md — 如何使用捆绑的触发器和输出评估文件。
- references/sources.md — 本次改写所用的上游文档和材料。