Convex:一条命令给 Expo 应用接上后端

Expo 和 Convex 把「应用有了、后端还没有」这段路压成一条命令:自动建项目、写环境变量、生成类型,之后 useQuery 会自己跟着数据更新。

中文
复制
Expo 与 Convex 的联名配图,写着「Convex is now a one-command backend for Expo apps」

本文是 Convex 开发者社区负责人 Wayne Sutton 的客座文章。一条 EAS CLI 命令,就能给你的 Expo 应用配好并接上一个响应式的、类型完整的 Convex 后端:不用单独注册、不用开一堆后台面板、不用来回复制 token。

我出去跟开发者聊天时,经常看到这样一个瞬间:应用你已经做完了,页面能跑、导航很顺、演示效果也很好;然后有人问了一句「数据存在哪儿」,你才想起来后端还没做。于是你去挑一个数据库、在某个地方注册账号、建项目、从面板里复制部署 URL、粘进环境配置、再为构建配置重复设置一遍同一个变量,然后在下一个跑这个项目的人踩坑之前祈祷自己全都填对了。

Expo 的人跟我说过,「我有一个应用」和「我有一个带后端的应用」之间这段路,多年来一直是 Expo 体验里最大的一块缺口。所以我们和他们一起把它补上了。现在你可以用一条命令,把 Convex(我所在的响应式数据库与后端平台)接到你的 Expo 应用上:

eas integrations:convex:connect

这条命令会替你把开通和接线全做完:引导流程里没有单独的 Convex 注册、没有 OAuth 跳转、不用在两个面板之间来回切。最后你得到的是一个类型完整、响应式的后端,以及一份已经配好本地开发和构建的环境变量。这是我最得意的一点:它感觉不像往项目里硬塞一个第三方服务,更像一个本来就在那儿的特性。

Convex 给了你什么

Convex 是一个后端平台,包含实时数据库、服务端函数、文件存储、搜索、定时调度,以及类型安全的客户端库。你用 TypeScript 写后端函数,客户端订阅它们;底层数据一变,你的 useQuery 结果会自己更新——不用手动重新拉取、不用写缓存失效代码、不用手写 REST 接口。

类型是从你的后端代码生成的,所以组件里调用的查询和你写在 convex/ 目录里的函数始终同步:你在服务端改掉一个字段名,TypeScript 会告诉你客户端哪里崩。我在 meetup 上见过很多开发者第一次撞上这一点,通常也就是他们身体前倾、开始认真听的那一刻。

什么时候该用它

当你的 Expo 应用需要存取「用户正看着的时候还在变」的数据时,就该用它:聊天、在线状态、实时比分、协作清单——任何「数据一变界面就该立刻更新」的场景。Convex 的订阅模型很适合这种形态,而且你不需要自己架 WebSocket 或者写轮询。

在项目早期,它也是最快的一条路——这是我最在意的一拨人:你有一个想法和一个 Expo 项目,想今天就有一个真后端,而不是一周之后。一条命令就能到那儿,之后你可以按需长成函数、调度和文件存储。

如果你的应用只是包在现有内部 API 外面的一层薄客户端,或者数据完全是静态的,那你大概不需要它。真正需要实时数据的时候,才伸手拿它。

怎么把 Convex 接到 Expo 应用上

你需要一个 Expo 账号、装好 EAS CLInpm install -g eas-cli),以及一个已经用 eas init 关联到 EAS 的 Expo 项目。

在项目目录里运行:

eas integrations:convex:connect

命令会询问部署区域、项目名,必要时问你团队名——只有在需要新建一个 Convex 团队连接时才会问团队名。你也可以一次性把参数都传进去:

eas integrations:convex:connect --region aws-us-east-1 --team-name "your-team" --project-name "your-app"

这条命令在背后做了这些事:

  • npx expo install convex 安装 convex
  • 为你的 EAS 账号创建一个 Convex 团队连接,或者复用已有的
  • 为这个 Expo 应用创建 Convex 项目和部署
  • CONVEX_DEPLOY_KEYEXPO_PUBLIC_CONVEX_URL 写进 .env.local
  • EXPO_PUBLIC_CONVEX_URL 设为 EAS 环境变量,覆盖 production、preview、development 三套环境
  • 往你的已验证邮箱发一封邀请,让你之后可以认领这个 Convex 团队并打开它的面板

最后一点值得单独说:邀请是异步的,所以你不用停下来等它、可以直接继续干活。马上把 Convex 的开发服务器起起来:

npx convex dev

它会(在你还没有的时候)创建本地的 convex/ 目录、生成带类型的 API 文件,并在运行期间让你的函数和部署保持同步。

然后给应用套上 provider。如果是 Expo Router 项目,就改 app/_layout.tsx

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>
  );
}

convex/ 目录里加一个查询函数:

import { query } from './_generated/server';

export const get = query({
  args: {},
  handler: async ctx => {
    return await ctx.db.query('tasks').collect();
  },
});

再在页面里调用它:

import { api } from '@/convex/_generated/api';
import { useQuery } from 'convex/react';
import { Text, View } from 'react-native';

export default function Index() {
  const tasks = useQuery(api.tasks.get);

  return (
    <View>
      {tasks?.map(task => (
        <Text key={task._id}>{task.text}</Text>
      ))}
    </View>
  );
}

在 Convex 面板里改一行数据,你设备上的列表就会更新。整个闭环就这么大。

用 agent 来配

我合作的很多开发者现在都用 AI agent 写代码,所以我也用这种方式测过。因为它只是一条命令、参数又很确定,所以当成给编码 agent 的指令非常合适。把下面这段粘给它就行:

在我的 Expo 项目里运行 eas integrations:convex:connect,开通并连接一个 Convex 后端。然后在 app/_layout.tsx 里加上 ConvexProvider,用 process.env.EXPO_PUBLIC_CONVEX_URL;在 convex/ 目录里写一个示例 tasks 查询,并在首页用 useQuery 渲染出来。

agent 需要的东西都齐了:没有面板要点、没有密钥需要你念给它听。

管理这个集成

之后可以用几条命令查看或修改这层关联:

eas integrations:convex:project
eas integrations:convex:dashboard
eas integrations:convex:team
eas integrations:convex:team:invite

如果你用 eas integrations:convex:project:deleteeas integrations:convex:team:delete 解绑,EAS 只会删掉它自己那部分集成元数据,不会动 Convex 上的任何东西——你的数据和部署都留在原地。

几件要知道的事

这条命令是发邮件邀请,而不是在流程里直接把你登进 Convex,所以完整的面板访问权限要等你认领之后才有。区域在首发时可选 aws-us-east-1aws-eu-west-1。另外 EXPO_PUBLIC_CONVEX_URL 按设计就是公开变量——客户端需要它才能访问你的部署;真正的密钥请放在 Convex 的环境变量或服务端函数里,不要放进应用包。

从哪儿开始

  • 一条命令就开通并接好后端,环境变量已经为本地开发和构建准备好。
  • 你得到一个响应式、类型完整的数据库:数据一变,useQuery 自己更新。
  • 解绑是安全的:它删掉的是 EAS 的元数据,不是你的 Convex 资源。

如果你已经有 Expo 项目,先 eas init,再 eas integrations:convex:connect,咖啡还没凉你就有后端了。完整教程在使用 Convex 指南Convex 概览则讲了文档、函数和订阅之间是怎么配合的。

做出来什么记得来告诉我。我常在 Convex Discord,也会看 Expo Discord。我很想知道它在哪儿帮你省了时间、又在哪儿卡住了你。

来源: Expo Blog← 返回首页