如何将 Prisma ORM 与 Turborepo 结合使用
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 schema 所在的位置。在这里,您将能够修改数据库的形状。默认情况下,prisma init
命令将创建用于PostgreSQL
的配置。您可以修改 schema 以使用 Prisma ORM 支持的任何其他数据库。.gitignore
向 git 添加一些忽略的文件.env
允许您手动为 prisma 指定DATABASE_URL
。
确保将 packages/database/.env
内的 DATABASE_URL
替换为有效的数据库 URL。
在 database/prisma/schema.prisma
中向您的 Prisma schema 添加模型
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 schema 生成类型,请从项目根目录运行
- 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
按照 Just-in-Time packaging pattern 并在 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
让我们从 web
应用程序的 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 设置!