
xiaofuyesnew
2023/02/14阅读:46主题:默认主题
从 Vercel 到 PlanetScale
本文详细介绍如何使用 Vercel 的 Serverless 功能为项目添加 API ,并使用 Prisma 连接 PlanetScale 数据库。
本文将不会涉及且基于读者已熟知并建立以下环境:
开发环境(Node.js/Git/VSCode...) Github 账号 科学上网

配置开发分支
承接上文,当我们向 Github 远程仓库推送代码后,Github Actions 和 Vercel 就会分别对代码进行构建和部署。
频繁的 commit 操作显然会消耗过多的构建和部署时长。对于 Github 来说,免费用户的构建时长是每月 2000 分钟;而对于 Vercel 来说,免费用户的构建时长是每月 6000 分钟。虽然免费额度不太可能用完,但频繁的构建确实显得浪费且没有必要。
因此,我们可以从本地项目代码中迁出一个 dev
分支,用于日常的开发:
$ git checkout -b dev
# 与远程仓库同步
$ git push -u origin dev
此时,对于触发构建的条件,我们有两种选择:其一,在 dev
分支开发完成后,将代码合并到 main
分支,再由 main
分支进行 push
操作触发构建,此种情况不用更改 workflow
脚本;其二,在 dev
分支开发完成后,push
到远程仓库,由远程仓库的 dev
分支向 main
分支提交 pull request
再触发构建,此种情况则需要对 .github/workflows/pages.yml
文件做如下修改:
...
on:
# push:
pull_request:
branches: [main]
...
当然,也可以保留两者,适用于任何代码合并的场景。
使用 Vercel 的 Serverless
Serverless 初体验
Vercel 本身是具备 Serverless 功能的,可以单独新建项目开发纯粹的 API 服务;而对于具有前端部分的项目,需要在项目根目录下创建 api
目录(只能命名为 api
)来当做 Serverless 的根目录。
进入 api
目录,并将其初始化:
$ cd api
$ pnpm init
如果你喜欢 ES module
方式导入模块,可以在生成的 package.json
中加入字段:
{
...
"type": "module"
...
}
也可以不加,就会自然保持 commonjs
的导入方式。下文中的代码示例,都是以 ES module
为例。
在 api
目录下新建 index.js
文件,然后简单写一个 Serverless
:
export default async (req, res) => {
const data = {
msg: 'Hello world!'
}
res.status(200).json(data)
}
提交 commit 构建部署后,在浏览器中直接打开 <project url>/api
,如果看到以下内容,则说明 API 部署成功:
{
msg: "Hello world!"
}
设置 Serverless 的开发模式
Vercel 提供了开发模式,便于在本地进行开发,而不用频繁部署到生产环境中,开启 Serverless 的开发模式,只需要在本地项目目录下执行如下命令:
# Vercel 命令行登录授权
$ npx vercel auth login
# 开启 Serverless 本地开发模式
$ npx vercel dev
命令会简单询问你几个问题,依次绑定好对应的权限和项目即可:

此时,在浏览器中访问 localhost:3000/api
即可看到在本地运行 Serverless 的返回结果。
如果同时要兼顾页面和接口的开发,有两种命令行方案:
-
打开两个终端窗口,分别执行 npx vercel dev
和vite
:
优点是各自的终端信息比较全面不会互相干扰;
缺点是需要打开两个窗口和执行两次命令。
-
在 package.json
中注册一个script
:
{
...,
"scripts": {
...,
"vercel:dev": "npx vercel dev | vite"
}
}
然后执行 pnpm vercel:dev
即可同时启动开发环境下的页面和接口服务。
优点是只需要开启一个终端界面,并执行一个指令就可以开启所有服务;
缺点是所有信息混在在一起,对各个开发部分会有一定干扰。
由于在开发环境中,页面和接口的服务在不同的端口提供,在页面开发中直接请求接口会有跨域限制,我们需要在 vite.config.js
中配置代理:
import { defineConfig } from 'vite'
export default defineConfig({
...,
server: {
proxy: {
'/api': {
target: 'http://localhost:3000/api',
changeOrigin: true,
rewrite: (path) => path.replace(/^\/api/, ''),
}
}
}
})
这样在请求时,只需要请求 /api
则会代理到本地的接口服务。同时,由于在 Vercel 生产环境页面和接口服务是同域名,则不存在跨域的情况,因此在生产环境可以不用做更多的处理。
PlanetScale 和 Prisma
PlanetScale 数据库的创建和配置
打开 planetscale.com
,同样可以使用 Github 账号进行授权登录。

PlanetScale 为免费用户提供了一个免费的数据库,这个数据库可以包含两个分支,同时,有一定的使用限制,如下图所示:

但对于一个个人博客项目来说,这个额度是足够的。
登录后,我们可以创建一个数据库:

通过 Region
来选择数据库实例所在的节点,建议根据地理位置选择离自己更近的节点。

创建好数据库后,可以点击 New Branch
创建一个开发分支,如下图:

创建好分支后,在任一分支的 Overview
界面下,点击 Promote a branch to production
按钮,来指定一个生产环境分支:

一般地,我们将 main
分支作为生产环境分支,而 dev
作为开发环境分支。
在两个分支的 Overview
界面中点击 Connect
按钮,PlanetScale 会生成对应数据库的连接凭证:

可以更改 Connect with
选项,查看不同连接方式的凭证使用介绍,此处我们选择 Prisma
:
将获取到的 DATABASE_URL
参数填写到 Vercel 项目配置的 Environment Variables
中配置环境变量:

这里,需要配置两个 DATABASE_URL
分别在开发环境和生产环境,对应 PlanetScale 数据库的开发分支和生产分支的访问凭证。
访问凭证配置在此处的目的是为了使敏感信息更安全,而不会随项目代码暴露出去。
使用 Prisma 连接数据库
让我们暂时回到本地项目目录,来到 api
目录,添加依赖,并初始化 Prisma :
$ pnpm add @prisma/client
$ pnpm add prisma -D
$ npx prisma init
初始化过程会在目录下生成 prisma/schema.prisma
和 .env
。
在 prisma/schema.prisma
中写入如下内容:
// 生成客户端
generator client {
provider = "prisma-client-js"
}
// 数据源连接凭证
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
relationMode = "prisma"
}
// User 数据表描述
model User {
id Int @id @default(autoincrement())
email String @unique
name String?
}
在 .env
中写入如下内容:
DATABASE_URL='mysql://root@127.0.0.1:3309/<database name>'
其中,<database name>
为 PlanetScale 上创建的数据库名称。
安装
PlanetScale CLI
:https://github.com/planetscale/cli/releases
从以上地址可以获取 PlanetScale CLI 的各平台最新版本,下载后解压后放置在任意路径,并将该路径注册进系统的环境变量中
在终端中使用
pscale version
来检测安装是否成功。
在终端中输入命令:
# 弹出页面验证授权
$ pscale auth login
# 连接数据库,并代理到本地 3309 端口
$ pscale connect <database name> <branch name> --port 3309
其中,<database name>
为数据库名称, <branch name>
为分支名称,此处可以为我们设置的开发分支 dev
。
本地代理端口可以更改,但需与 .env
中 DATABASE_URL
描述的端口保持一致。
然后再打开一个终端,输入命令:
$ npx prisma db push
执行完毕后,我们可以去查看 PlanetScale 的控制台的 Schema 界面,里面有相应的 User
表,则证明我们的数据结构操作已经成功:

此时,就可以在数据表中添加一些数据,此处笔者直接使用 Prisma studio
进行操作:
$ npx prisma studio
在弹出的页面中操作添加一条记录:

接下来,我们处理一下 Serverless 的代码。
首先,我们在 api
目录下创建 lib/prisma.js
,其内容如下:
import { PrismaClient } from '@prisma/client'
const prisma = global.prisma || new PrismaClient()
if (process.env.NODE_ENV === 'development') global.prisma = prisma
export default prisma
其目的在于在开发环境下创建 PrismaClient 的单例。
然后,我们修改一下 index.js
的内容:
import prisma from './lib/prisma.js'
export default async (req, res) => {
const users = await prisma.user.findMany()
const data = {
msg: 'Hello world!',
data: users
}
res.status(200).json(data)
}
开启本地开发服务,访问 localhost:3000/api
就会得到如下结果:
{
msg: "Hello world!",
data: [
{
id: 1,
email: "test_user@test.com",
name: "user_development"
}
]
}
说明在开发环境中,完整打通了从 Serverless 到数据库的开发链路,可以进一步编写接口的业务逻辑。
数据库部署
当我们开发好相关的 Serverless 功能,数据库结构也相应固定下来时,就可以进行部署操作了。
前文已经介绍了 Serverless 的部署,此处不再赘述,但需要补充的是,因为 Vercel Serverless 的构建不会进行 Prisma Client 的生成,因此需要在提交代码部署之前于 api
目录下的 package.json
中添加一条 script 钩子
:
{
...,
"scripts": {
...,
"postinstall": "prisma generate"
}
}
下面我们着重介绍数据库的部署:
首先,我们需要将数据库的 dev
分支通过 deploy request
合并到 main
分支上:

当确认 deploy request
之后,两表的结构就合并了。
然后,在终端窗口建立数据库生产分支的代理:
$ pscale connect tutorial main --port 3309
打开一个新的终端,使用 Prisma studio
连接数据库:
$ npx prisma studio
创建一条记录:

然后,确保 Serverless 部署和数据库都准备妥当后,访问 <project url>/api
,如果出现以下内容:
{
msg: "Hello world!",
data: [
{
id: 1,
email: "test_user@test.com",
name: "test_production"
}
]
}
则说明部署生产环境已经成功。
总结
在本文中,我们首先区分了项目的开发环境和生产环境,并从 Vercel 的 Serverless 功能出发,通过 Prisma 在 Serverless 中添加访问 PlanetScale 数据库的能力。
至此,一套完整的、围绕 Github, Vercel, PlanetScale, Prisma 功能的个人博客系统开发工作流已经完全打通,后续的关注点就将逐步转移到具体业务功能的实现上。
前文拾遗
在上文中,我们创建了 gh-pages
分支用于承载构建后的文件,用于部署至 Github Pages 。但在触发 Vercel 构建后,Vercel 会进行 Preview Deployment
,而它的默认拉取分支就是 gh-pages
。这会造成 Vercel 的构建错误,如下图:

解决方法就是,在项目的 Settings > Git > Ignored Build Step
中配置:
# Command
[ "$VERCEL_ENV" != production ]
这可以阻止触发 非production
的构建。
同时,因为构建会触发 Github 通知,会默认发送通知和邮件,如果觉得没有必要或觉得受到打扰,可以在项目中添加 vercel.json
配置文件,然后增加如下部分:
{
...,
"github": {
"silent": true
}
}
如对该文章涉及到的话题感兴趣,可关注
【开源说】微信公众号
回复【关注】或【作者】
长按二维码加好友,备注【开源说】
作者介绍

xiaofuyesnew
武汉般若互动-前端TL