如何在 Turborepo 中使用 Prisma ORM
Prisma 是一个用于管理数据库的强大 ORM,而 Turborepo 简化了 monorepo 工作流程。通过结合使用这些工具,您可以为您的项目创建可扩展的模块化架构。
本指南将向您展示如何在 Turborepo monorepo 中将 Prisma 设置为独立包,从而实现跨多个应用程序的高效配置、类型共享和数据库管理。
您将学到什么:
- 如何在 Turborepo monorepo 中设置 Prisma。
- 跨包生成和重用 PrismaClient 的步骤。
- 将 Prisma 包集成到 monorepo 中的其他应用程序中。
本指南已使用 Turborepo 版本 2.3.3
和 Prisma ORM 版本 6.1.0
进行了测试。
1. 使用 turborepo 创建您的 monorepo
要设置一个名为 hello-world
的 Turborepo monorepo,请运行以下命令
npx create-turbo@latest hello-world
设置完成后,为项目选择一个包管理器。导航到项目根目录,并将 Turborepo 安装为开发依赖项
- npm
- yarn
- pnpm
cd ./hello-world
npm install turbo --save-dev
cd ./hello-world
yarn add turbo --dev --ignore-workspace-root-check
cd ./hello-world
pnpm add turbo --save-dev --ignore-workspace-root-check
有关安装 Turborepo 的更多信息,请参阅 官方 Turborepo 指南。
2. 向 hello-world
monorepo 添加一个新的 database
包
在 packages
目录中创建一个 database
包。然后,通过运行以下命令为该包创建一个 package.json
文件
cd packages/
mkdir database
cd database
touch package.json
按如下方式定义 package.json
文件
{
"name": "@repo/db",
"version": "0.0.0"
}
接下来,安装使用 Prisma ORM 所需的依赖项。使用您首选的包管理器
- npm
- yarn
- pnpm
npm install prisma --save-dev
npm install @prisma/client
yarn add prisma --dev
yarn add @prisma/client
pnpm add prisma --save-dev
pnpm add @prisma/client
3. 通过运行 prisma init
初始化 prisma
在 database
目录中,通过运行以下命令初始化 prisma
- npm
- yarn
- pnpm
npx prisma init
yarn prisma init
pnpm prisma init
这应该在 packages/database
中创建几个文件
schema.prisma
是您的 Prisma 模式所在的位置。在这里,您可以修改数据库的形状。默认情况下,prisma init
命令将创建用于PostgreSQL
的配置。您可以修改该模式以使用 Prisma ORM 支持的任何其他受支持的数据库。.gitignore
将一些忽略的文件添加到 git.env
允许您手动为 prisma 指定DATABASE_URL
。
请确保将 packages/database/.env
内的 DATABASE_URL
替换为有效的数据库 URL。
在 database/prisma/schema.prisma
中向您的 Prisma 模式添加一个模型
datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
output = "../generated/client"
}
model User {
id Int @id @default(autoincrement())
createdAt DateTime @default(now())
email String @unique
name String?
}
在 自定义目录中生成 Prisma 类型的重要性
在 schema.prisma
文件中,我们指定了一个自定义的 output
路径,Prisma 将在此路径中生成其类型。这可确保在不同的包管理器中正确解析 Prisma 的类型。
在本指南中,这些类型将在
database/generated/client
目录中生成。
4. 创建脚本来执行 Prisma CLI 命令
让我们在 packages/database
内的 package.json
中添加一些脚本
{
"scripts": {
"db:generate": "prisma generate",
"db:migrate": "prisma migrate dev --skip-generate",
"db:deploy": "prisma migrate deploy"
}
}
让我们也将这些脚本添加到根目录中的 turbo.json
中
{
"tasks": {
"db:generate": {
"cache": false
},
"db:migrate": {
"cache": false,
"persistent": true // This is necessary to interact with the CLI and assign names to your database migrations.
},
"db:deploy": {
"cache": false
}
}
}
1. 迁移您的 prisma.schema
并生成类型
导航到项目根目录并运行以下命令来自动迁移我们的数据库
- npm
- yarn
- pnpm
npx turbo db:migrate
yarn turbo db:migrate
pnpm turbo db:migrate
2. 生成您的 prisma.schema
要从 Prisma 模式生成类型,请从项目根目录运行
- npm
- yarn
- pnpm
npx turbo db:generate
yarn turbo db:generate
pnpm turbo db:generate
5. 导出 prisma 类型和 PrismaClient
的实例以在 monorepo 中使用
接下来,导出生成的类型和 PrismaClient
的实例,以便在您的应用程序中使用。
在 packages/database
目录中,创建一个 src
文件夹并添加一个 client.ts
文件。此文件将定义 PrismaClient
的实例
import { PrismaClient } from "../generated/client";
const globalForPrisma = global as unknown as { prisma: PrismaClient };
export const prisma =
globalForPrisma.prisma || new PrismaClient();
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
然后在 src
文件夹中创建一个 index.ts
文件,以重新导出生成的 prisma 类型和 PrismaClient
实例
export { prisma } from './client' // exports instance of prisma
export * from "../generated/client" // exports generated types from prisma
遵循 即时打包模式并在 packages/database/package.json
中创建一个包的入口点
{
"exports": {
".": "./src/index.ts"
}
}
完成这些步骤后,您将使 Prisma 类型和 PrismaClient
实例在整个 monorepo 中都可访问。
6. 将 database
包导入 monorepo 中的 web
应用程序
hello-world
项目应在 apps/web
处有一个名为 web
的应用程序。将 database
依赖项添加到 apps/web/package.json
- npm
- yarn
- pnpm
{
"dependencies": {
"@repo/db": "*"
}
}
{
"dependencies": {
"@repo/db": "*"
}
}
{
"dependencies": {
"@repo/db": "workspace:*"
}
}
在 apps/web
目录中运行您的包管理器的安装命令
- npm
- yarn
- pnpm
cd apps/web
npm install
cd apps/web
yarn install
cd apps/web
pnpm install
让我们在 page.tsx
文件中从 database
包中导入实例化的 prisma
客户端
import styles from "./page.module.css";
import { prisma } from "@repo/db";
export default async function Home() {
const user = await prisma.user.findFirst()
return (
<div className={styles.page}>
{user?.name ?? "No user added yet"}
</div>
);
}
然后在 web
目录中创建一个 .env
文件,并复制 database
目录中包含 DATABASE_URL
的 .env
文件的内容。
DATABASE_URL="Same database url as used in the database directory"
如果您想在 Turborepo 设置中跨应用程序和包使用根目录中的单个 .env
文件,请考虑使用诸如 dotenvx
之类的包。
要实现此目的,请更新每个包或应用程序的 package.json
文件,以确保它们从共享的 .env
文件加载所需的环境变量。有关详细说明,请参阅 dotenvx
Turborepo 指南。
请记住,Turborepo 建议为每个包使用单独的 .env
文件,以提高模块化并避免潜在的冲突。
7. 设置依赖任务
db:generate
和 db:deploy
脚本尚未针对 monorepo 设置进行优化,但对于 dev
和 build
任务至关重要。
如果新开发人员在没有首先运行 db:generate
的情况下在应用程序上运行 turbo dev
,他们将会遇到错误。
为了防止这种情况,请确保在运行 dev
或 build
之前始终执行 db:generate
。此外,确保在 db:build
之前执行 db:deploy
和 db:generate
。以下是如何在 turbo.json
文件中配置此项的方法
{
"tasks": {
"dev": {
"dependsOn": ["^db:generate"],
"cache": false
// Additional configuration for dev tasks
},
"build": {
"dependsOn": ["^db:generate"],
// Additional configuration for build tasks
}
}
}
8. 在开发环境中运行项目
然后从项目根目录运行项目
- npm
- yarn
- pnpm
npx turbo run dev --filter=web
yarn turbo run dev --filter=web
pnpm turbo run dev --filter=web
导航到 https://127.0.0.1:3000
,您应该会看到消息
No user added yet
您可以通过创建种子脚本或使用 Prisma Studio 手动向数据库添加用户。
要使用 Prisma Studio 通过 GUI 手动添加数据,请导航到 packages/database
目录并使用您的包管理器运行 prisma studio
- npm
- yarn
- pnpm
npx prisma studio
yarn prisma studio
pnpm prisma studio
此命令会启动一个服务器,其 GUI 位于 https://127.0.0.1:5555,允许您查看和修改数据。
恭喜,您已完成为 Turborepo 设置 Prisma!