Nuxt+Supabase 集成开发
前言
此前一直在使用 Nuxt 开发各种小项目。后面接了一些需求,发现其实挺多项目都是大同小异的,像是数据库、用户认证,文件存储等等,虽然说 Nuxt 也有对应的插件能够实现这些功能,比如:
但是每次集成这些功能都需要花费不少时间去调试和配置,感觉挺麻烦的。最近 Prisma 更新了 v7 版本,schema 大改了之后又要重新熟悉一遍,实在是令人头疼。于是我在想是否有能够将常见后端服务一并集成的 BaaS 方案。
之前写微信小程序的时候用的是 Cloudbase 云开发,体验不是很好。至于 Firebase,国内开发还是不太方便的。一番调研下来,才了解到有 Supabase 这样的开源 BaaS 方案,功能上和 Firebase 类似,但更适合国内开发者使用。另外还有个 Pocketbase,是 Go 单体应用很轻量,但用的是 SQLite 数据库,虽然说我写的项目也没几个人用,但是还是想用更成熟的方案。最终我选择了 Supabase。
Supabase 提供了 Postgres 数据库、用户认证、文件存储、实时订阅等功能,基本上覆盖了我大部分项目的需求。也有 JavaScript 和移动端等各种平台的 SDK 库,可以很方便地集成到各种项目中。
为什么是 Nuxt
既然 Supabase 提供了 Edge Functions,可以直接写后端逻辑,为什么还要用 Nuxt 呢?作为习惯了 Nuxt 的 useFetch 自动导出函数返回类型的开发者来说,体验之后就回不去了。
但经过我的一番调查,我发现 Supabase 的 Edge Functions 没法向前端共享类型,所以前端调用接口时很容易抓瞎。虽然说我们是前后端分离人不分离,但是前端全是 any 还是很让人心惊肉跳的。虽说 Supabase 的 数据库 RPC 函数是可以通过 supabase gen types 生成类型定义的,但是那也只能覆盖一部分的纯数据库业务,对于一些需要外部请求的函数也是无能为力,所以我更倾向于不使用 RPC 的方式。
而且 Edge Functions 是可以免鉴权直接操作 Supabase 的,如果我们使用其他的后端,就要自己处理鉴权逻辑,增加了不少工作量。难道说就要折服于 Edge Functions 了吗?这时我发现 nuxtjs/supabase 里居然是有服务端相关的 API 接口的,他已经帮我们处理好了鉴权逻辑,我们只需要在 Nuxt 里调用就行了。那还说啥了,直接上 Nuxt 吧!
创建项目
Supabase 的文档实在难懂,我就不多说了,直接给出我琢磨出的创建步骤吧。
首先是熟悉的创建 Nuxt 项目:
$ pnpm create nuxt@latest
...
◇ Which template would you like to use?
│ minimal – Minimal setup for Nuxt 4
│
◇ Where would you like to create your project?
│ ./supanuxt
│
◇ Creating project in supanuxt
│
◇ Downloaded minimal template
│
◇ Which package manager would you like to use?
│ pnpm
│
◇ Initialize git repository?
│ Yes
...
然后安装 Supabase
$ cd supanuxt
# Supabase CLI 不能全局安装,这里安装到本地开发依赖
$ pnpm i supabase -D
# 注意需要允许 postinstall 才能生成,不然是找不到 supabase 的可执行文件的
$ pnpm approve-builds
√ Choose which packages to build (Press <space> to select, <a> to toggle all, <i> to invert selection) · supabase
√ The next packages will now be built: supabase.
Do you approve? (y/N) · true
之后初始化 Supabase 项目
$ pnpm supabase init
Finished supabase init.
之后就可以看到项目下生成了一个 supabase 目录啦,可以在 config.toml 里配置登录源、文件存储之类各种后端服务。
准备好之后,运行 pnpm supabase start 就可以启动 Supabase 本地开发环境了。注意如果你使用的是 Windows,需要先安装 Docker Desktop 来支持 Docker 操作。
$ pnpm supabase start
...
╭──────────────────────────────────────╮
│ 🔧 Development Tools │
├─────────┬────────────────────────────┤
│ Studio │ http://127.0.0.1:54323 │
│ Mailpit │ http://127.0.0.1:54324 │
│ MCP │ http://127.0.0.1:54321/mcp │
╰─────────┴────────────────────────────╯
╭──────────────────────────────────────────────────────╮
│ 🌐 APIs │
├────────────────┬─────────────────────────────────────┤
│ Project URL │ http://127.0.0.1:54321 │
│ REST │ http://127.0.0.1:54321/rest/v1 │
│ GraphQL │ http://127.0.0.1:54321/graphql/v1 │
│ Edge Functions │ http://127.0.0.1:54321/functions/v1 │
╰────────────────┴─────────────────────────────────────╯
╭───────────────────────────────────────────────────────────────╮
│ ⛁ Database │
├─────┬─────────────────────────────────────────────────────────┤
│ URL │ postgresql://postgres:postgres@127.0.0.1:54322/postgres │
╰─────┴─────────────────────────────────────────────────────────╯
╭──────────────────────────────────────────────────────────────╮
│ 🔑 Authentication Keys │
├─────────────┬────────────────────────────────────────────────┤
│ Publishable │ sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH │
│ Secret │ sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz │
╰─────────────┴────────────────────────────────────────────────╯
...
其中 Development Tools > Studio 是 Supabase 的管理后台,可以直接访问这个地址进行数据库表设计、用户管理、文件存储等操作。
最后安装 Nuxt Supabase 模块就可以在 Nuxt 里愉快地使用 Supabase 了。
$ pnpx nuxi@latest module add supabase
完成后需要在 .env 里配置 Supabase 连接参数,就是上面的 APIs > Project URL 和 Authentication Keys 里的内容:
SUPABASE_URL=http://127.0.0.1:54321
SUPABASE_KEY=sb_publishable_ACJWlzQHlZjBrEguHvfOxg_3BJgxAaH
SUPABASE_SECRET_KEY=sb_secret_N7UND0UgjKTVK-Uodkm0Hg_xSvEMPvz
每次更改数据库结构后,可以通过下面的命令同步类型定义给 nuxtjs/supabase:
$ supabase gen types typescript --local > .app/types/database.types.ts
如果你想要停止 Supabase 本地开发环境,可以运行:
$ pnpm supabase stop
其他常见的命令可以在 Supabase CLI 文档里查看。
部署项目
上面的操作都是在本地开发环境进行的,接下来我们需要把 Supabase 部署到线上环境。如果你使用的是 Supabase 官方托管服务,只需要执行下面的命令就可以了:
$ pnpm supabase login
Hello from Supabase! Press Enter to open browser and login automatically.
Here is your login link in case browser did not open https://supabase.com/dashboard/cli/login?...
Enter your verification code: 6faf51e0
Token ... created successfully.
You are now logged in. Happy coding!
如果你的部署环境是自托管的话也没关系,Supbase CLI 文档里大部分命令都同时提供了官方服务和自托管两种方式,一般只需要在命令后加上 --db-url 就可以了。
这里讲解几个概念:
supabase/seed.sql:数据库初始化脚本,在第一次创建数据库时会自动执行这个脚本,可以用来插入一些初始数据,具体可以参考 seeding your databasesupabase/migrations/*.sql:数据库迁移文件,每次对数据库模式进行修改时,都会生成一个新的 migration 文件,方便版本控制和回滚supabase/schemas/*.sql:数据库模式文件,可以通过文件的方式管理数据库模式,从而被版本控制,具体可以参考 declarative database schemas
下面是一些常用的 CLI 命令:
supabase db pull:从线上数据库拉取 migrations 到本地 supabase/migrations 目录supabase db push:将本地 supabase/migrations 目录的迁移文件推送到线上数据库supabase db dump -f supabase/schemas/prod.sql:导出线上数据库模式supabase db diff -f new-migration:对比线上数据库和本地数据库模式,生成新的迁移文件supabase db reset:重置本地数据库,会清空所有数据
接入第三方登录
TODO