跳到主要内容

如何将 Prisma ORM 与 Turborepo 结合使用

15 分钟

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 安装为开发依赖项

cd ./hello-world
npm install turbo --save-dev

有关安装 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 install prisma --save-dev
npm install @prisma/client

3. 通过运行 prisma init 初始化 prisma

database 目录中,通过运行以下命令初始化 prisma

npx 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 并生成类型

导航到项目根目录并运行以下命令以自动迁移我们的数据库

npx turbo db:migrate

2. 生成您的 prisma.schema

要从 Prisma schema 生成类型,请从项目根目录运行

npx turbo db:generate

5. 导出 prisma 类型和 PrismaClient 实例以在 monorepo 中使用

接下来,导出生成的类型和 PrismaClient 实例,以便可以在您的应用程序中使用。

packages/database 目录中,创建一个 src 文件夹并添加一个 client.ts 文件。此文件将定义 PrismaClient 的实例

packages/database/src/client.ts
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 实例

packages/database/src/index.ts
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

{
"dependencies": {
"@repo/db": "*"
}
}

apps/web 目录内运行您的包管理器的安装命令

cd apps/web
npm 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:generatedb:deploy 脚本尚未针对 monorepo 设置进行优化,但对于 devbuild 任务至关重要。

如果新开发人员在没有首先运行 db:generate 的情况下在应用程序上运行 turbo dev,他们将遇到错误。

为防止这种情况,请确保始终在运行 devbuild 之前执行 db:generate。此外,确保在 db:build 之前执行 db:deploydb: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. 在开发中运行项目

然后从项目根目录运行项目

npx turbo run dev --filter=web

导航到 https://127.0.0.1:3000,您应该看到消息

No user added yet
注意

您可以通过创建种子脚本或手动使用 Prisma Studio 向数据库添加用户。

要使用 Prisma Studio 通过 GUI 手动添加数据,请导航到 packages/database 目录内部并使用您的包管理器运行 prisma studio

npx prisma studio

此命令启动一个服务器,GUI 位于 https://127.0.0.1:5555,允许您查看和修改数据。

恭喜,您已完成 Turborepo 的 Prisma 设置!