Skip to main content

如何在 Turborepo 中使用 Prisma ORM

15 min

Prisma 是一个功能强大的数据库 ORM,Turborepo 简化了单一存储库的工作流程。通过组合使用这些工具,你可以为你的项目创建可扩展的模块化架构。

¥Prisma is a powerful ORM for managing databases, and Turborepo simplifies monorepo workflows. By combining these tools, you can create a scalable, modular architecture for your projects.

本指南将向你展示如何在 Turborepo monorepo 中将 Prisma 设置为独立包,从而实现跨多个应用的高效配置、类型共享和数据库管理。

¥This guide will show you how to set up Prisma as a standalone package in a Turborepo monorepo, enabling efficient configuration, type sharing, and database management across multiple apps.

你将学习的内容:

¥What you'll learn:

  • 如何在 Turborepo monorepo 中设置 Prisma。

    ¥How to set up Prisma in a Turborepo monorepo.

  • 在各个包中生成和重用 PrismaClient 的步骤。

    ¥Steps to generate and reuse PrismaClient across packages.

  • 将 Prisma 包集成到 monorepo 中的其他应用中。

    ¥Integrating the Prisma package into other applications in the monorepo.

先决条件

¥Prerequisites

1. 设置你的项目

¥ Set up your project

要设置名为 turborepo-prisma 的 Turborepo monorepo,请运行以下命令:

¥To set up a Turborepo monorepo named turborepo-prisma, run the following command:

npx create-turbo@latest turborepo-prisma

系统将提示你选择包管理器,本指南将使用 npm

¥You'll be prompted to select your package manager, this guide will use npm:

信息
  • 你想使用哪个软件包管理器?npm

    ¥Which package manager do you want to use? npm

设置完成后,为项目选择一个包管理器。进入项目根目录并将 Turborepo 安装为开发依赖:

¥After the setup, choose a package manager for the project. Navigate to the project root directory and install Turborepo as a development dependency:

cd turborepo-prisma
npm install turbo --save-dev

有关安装 Turborepo 的更多信息,请参阅 官方 Turborepo 指南

¥For more information about installing Turborepo, refer to the official Turborepo guide.

2. 将新的 database 包添加到 monorepo

¥ Add a new database package to the monorepo

2.1 创建软件包并安装 Prisma

¥2.1 Create the package and install Prisma

packages 目录中创建一个 database 包。然后,通过运行以下命令为包创建一个 package.json 文件:

¥Create a database package within the packages directory. Then, create a package.json file for the package by running:

cd packages/
mkdir database
cd database
touch package.json

按如下方式定义 package.json 文件:

¥Define the package.json file as follows:

packages/database/package.json
{
"name": "@repo/db",
"version": "0.0.0"
}

接下来,安装使用 Prisma ORM 所需的依赖。使用你首选的软件包管理器:

¥Next, install the required dependencies to use Prisma ORM. Use your preferred package manager:

npm install prisma --save-dev
npm install @prisma/client
注意

如果使用 Prisma Postgres,请安装 @prisma/extension-accelerate 包:

¥If using Prisma Postgres, install the @prisma/extension-accelerate package:

npm install @prisma/extension-accelerate

2.2.初始化 Prisma 并定义模型

¥2.2. Initialize Prisma and define models

database 目录中,运行以下命令初始化 Prisma:

¥Inside the database directory, initialize prisma by running:

npx prisma init --db --output ../generated/prisma

这将在 packages/database 中创建多个文件:

¥This will create several files inside packages/database:

  • 一个包含 schema.prisma 文件的 prisma 目录。

    ¥A prisma directory with a schema.prisma file.

  • 一个 Prisma Postgres 数据库。

    ¥A Prisma Postgres database.

  • 一个位于项目根目录、包含 DATABASE_URL 文件的 .env 文件。

    ¥A .env file containing the DATABASE_URL at the project root.

  • 用于生成的 Prisma 客户端的 output 目录,用作 generated/prisma

    ¥An output directory for the generated Prisma Client as generated/prisma.

packages/database/prisma/schema.prisma 文件中,添加以下模型:

¥In the packages/database/prisma/schema.prisma file, add the following models:

packages/database/prisma/schema.prisma
generator client {
provider = "prisma-client-js"
output = "../generated/prisma"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

model User {
id Int @id @default(autoincrement())
email String @unique
name String?
posts Post[]
}

model Post {
id Int @id @default(autoincrement())
title String
content String?
published Boolean @default(false)
authorId Int
author User @relation(fields: [authorId], references: [id])
}
警告

建议将 ../generated/prisma 添加到你的 .gitignore 文件中,因为它包含特定于平台的二进制文件,可能会导致不同环境之间的兼容性问题。

¥It is recommended to add ../generated/prisma to the .gitignore file because it contains platform-specific binaries that can cause compatibility issues across different environments.

在自定义目录中生成 Prisma 类型的重要性

¥The importance of generating Prisma types in a custom directory

schema.prisma 文件中,我们指定 Prisma 将在其中生成其类型的自定义 output 路径。这可确保 Prisma 的类型在不同的包管理器之间得到正确解析。

¥In the schema.prisma file, we specify a custom output path where Prisma will generate its types. This ensures Prisma's types are resolved correctly across different package managers.

信息

在本指南中,类型将在 database/generated/prisma 目录中生成。

¥In this guide, the types will be generated in the database/generated/prisma directory.

2.3.添加脚本并运行迁移

¥2.3. Add scripts and run migrations

让我们在 packages/database 中的 package.json 中添加一些脚本:

¥Let's add some scripts to the package.json inside packages/database:

packages/database/package.json
{
"name": "@repo/db",
"version": "0.0.0",
"scripts": {
"db:generate": "prisma generate",
"db:migrate": "prisma migrate dev --skip-generate",
"db:deploy": "prisma migrate deploy"
},
"devDependencies": {
"prisma": "^6.6.0"
},
"dependencies": {
"@prisma/client": "^6.6.0"
}
}

我们还需要在根目录中将这些脚本添加到 turbo.json 中,并确保 DATABASE_URL 已添加到环境中:

¥Let's also add these scripts to turbo.json in the root and ensure that DATABASE_URL is added to the environment:

turbo.json
{
"$schema": "https://turbo.build/schema.json",
"ui": "tui",
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", ".env*"],
"outputs": [".next/**", "!.next/cache/**"],
"env": ["DATABASE_URL"]
},
"lint": {
"dependsOn": ["^lint"]
},
"check-types": {
"dependsOn": ["^check-types"]
},
"dev": {
"cache": false,
"persistent": true
},
"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
}
}

迁移你的 prisma.schema 并生成类型

¥Migrate your prisma.schema and generate types

进入项目根目录并运行以下命令自动迁移数据库:

¥Navigate to the project root and run the following command to automatically migrate our database:

npx turbo db:migrate

生成你的 prisma.schema

¥Generate your prisma.schema

要从 Prisma 模式生成类型,请从项目根目录运行:

¥To generate the types from Prisma schema, from the project root run:

npx turbo db:generate

2.4.导出 Prisma 客户端和类型

¥2.4. Export the Prisma client and types

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

¥Next, export the generated types and an instance of PrismaClient so it can used in your applications.

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

¥In the packages/database directory, create a src folder and add a client.ts file. This file will define an instance of PrismaClient:

packages/database/src/client.ts
import { PrismaClient } from "../generated/prisma";
import { withAccelerate } from "@prisma/extension-accelerate";

const globalForPrisma = global as unknown as { prisma: PrismaClient };

export const prisma =
globalForPrisma.prisma || new PrismaClient().$extends(withAccelerate());

if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;

然后在 src 文件夹中创建一个 index.ts 文件,以重新导出生成的 Prisma 类型和 PrismaClient 实例:

¥Then create an index.ts file in the src folder to re-export the generated prisma types and the PrismaClient instance:

packages/database/src/index.ts
export { prisma } from './client' // exports instance of prisma 
export * from "../generated/prisma" // exports generated types from prisma

按照 即时打包模式 的步骤,在 packages/database/package.json 中创建指向包的入口点:

¥Follow the Just-in-Time packaging pattern and create an entrypoint to the package inside packages/database/package.json:

警告

如果你不使用打包器,请改用 已编译的软件包 策略。

¥If you're not using a bundler, use the Compiled Packages strategy instead.

packages/database/package.json
{
"name": "@repo/db",
"version": "0.0.0",
"scripts": {
"db:generate": "npx prisma generate",
"db:migrate": "npx prisma migrate dev --skip-generate",
"db:deploy": "npx prisma migrate deploy"
},
"devDependencies": {
"prisma": "^6.6.0"
},
"dependencies": {
"@prisma/client": "^6.6.0"
},
"exports": {
".": "./src/index.ts"
}
}

完成这些步骤后,你将使 Prisma 类型和 PrismaClient 实例可在整个 monorepo 中访问。

¥By completing these steps, you'll make the Prisma types and PrismaClient instance accessible throughout the monorepo.

3. 在 Web 应用中导入 database

¥ Import the database package in the web app

turborepo-prisma 项目应该在 apps/web 处有一个名为 web 的应用。将 database 依赖添加到 apps/web/package.json

¥The turborepo-prisma project should have an app called web at apps/web. Add the database dependency to apps/web/package.json:

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

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

¥Run your package manager's install command inside the apps/web directory:

cd apps/web
npm install

让我们从 web 应用中的 database 包中导入实例化的 prisma 客户端。

¥Let's import the intantiated prisma client from the database package in the web app.

apps/web/app 目录中,打开 page.tsx 文件并添加以下代码:

¥In the apps/web/app directory, open the page.tsx file and add the following code:

apps/web/app/page.tsx
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_URL/database 目录中的 .env 文件的内容复制到该文件中:

¥Then, create a .env file in the web directory and copy into it the contents of the .env file from the /database directory containing the DATABASE_URL:

apps/web/.env
DATABASE_URL="Same database url as used in the database directory"
注意

如果你想在 Turborepo 设置中跨应用和包在根目录中使用单个 .env 文件,请考虑使用像 dotenvx 这样的包。

¥If you want to use a single .env file in the root directory across your apps and packages in a Turborepo setup, consider using a package like dotenvx.

要实现此操作,请更新每个软件包或应用的 package.json 文件,以确保它们从共享的 .env 文件加载所需的环境变量。有关详细说明,请参阅 dotenvx Turborepo 指南

¥To implement this, update the package.json files for each package or app to ensure they load the required environment variables from the shared .env file. For detailed instructions, refer to the dotenvx guide for Turborepo.

请记住,Turborepo 建议为每个包使用单独的 .env 文件 是为了促进模块化并避免潜在的冲突。

¥Keep in mind that Turborepo recommends using separate .env files for each package to promote modularity and avoid potential conflicts.

4. 在 Turborepo 中配置任务依赖

¥ Configure task dependencies in Turborepo

db:generatedb:deploy 脚本尚未针对 monorepo 设置进行优化,但对于 devbuild 任务至关重要。

¥The db:generate and db:deploy scripts are not yet optimized for the monorepo setup but are essential for the dev and build tasks.

如果新开发者在未先运行 db:generate 的情况下在应用上运行 turbo dev,则会遇到错误。

¥If a new developer runs turbo dev on an application without first running db:generate, they will encounter errors.

为防止这种情况,请确保始终在运行 devbuild 之前执行 db:generate。此外,请确保 db:deploydb:generate 都在 db:build 之前执行。以下是如何在 turbo.json 文件中进行配置:

¥To prevent this, ensure that db:generate is always executed before running dev or build. Additionally, make sure both db:deploy and db:generate are executed before db:build. Here's how to configure this in your turbo.json file:

turbo.json
{
"$schema": "https://turbo.build/schema.json",
"ui": "tui",
"tasks": {
"build": {
"dependsOn": ["^build", "^db:generate"],
"inputs": ["$TURBO_DEFAULT$", ".env*"],
"outputs": [".next/**", "!.next/cache/**"],
"env": ["DATABASE_URL"]
},
"lint": {
"dependsOn": ["^lint"]
},
"check-types": {
"dependsOn": ["^check-types"]
},
"dev": {
"dependsOn": ["^db:generate"],
"cache": false,
"persistent": true
},
"db:generate": {
"cache": false
},
"db:migrate": {
"cache": false,
"persistent": true
},
"db:deploy": {
"cache": false
}
}
}

5. 运行开发中的项目

¥ Run the project in development

警告

在启动开发服务器之前,请注意,如果你使用的是 Next.js v15.2.0,请勿使用 Turbopack,因为存在已知的 issue。通过更新你的 apps/web/package.json 脚本,从你的开发脚本中移除 Turbopack

¥Before starting the development server, note that if you are using Next.js v15.2.0, do not use Turbopack as there is a known issue. Remove Turbopack from your dev script by updating your apps/web/package.json

apps/web/package.json
"script":{
"dev": "next dev --port 3000",
}

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

¥Then from the project root run the project:

npx turbo run dev --filter=web

进入 http://localhost:3000 目录,你应该会看到以下消息:

¥Navigate to the http://localhost:3000 and you should see the message:

No user added yet
注意

你可以通过创建种子脚本或手动使用 Prisma 工作室 将用户添加到数据库。

¥You can add users to your database by creating a seed script or manually by using Prisma Studio.

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

¥To use Prisma Studio to add manually data via a GUI, navigate inside the packages/database directory and run prisma studio using your package manager:

npx prisma studio

此命令在 http://localhost:5555 处启动一个带有 GUI 的服务器,允许你查看和修改数据。

¥This command starts a server with a GUI at http://localhost:5555, allowing you to view and modify your data.

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

¥Congratulations, you're done setting up Prisma for Turborepo!

后续步骤

¥Next Steps

  • 扩展你的 Prisma 模型以处理更复杂的数据关系。

    ¥Expand your Prisma models to handle more complex data relationships.

  • 实现额外的 CRUD 操作以增强应用的功能。

    ¥Implement additional CRUD operations to enhance your application's functionality.

  • 查看 Prisma Postgres,了解如何扩展你的应用。

    ¥Check out Prisma Postgres to see how you can scale your application.

更多信息

¥More Info


Stay connected with Prisma

Continue your Prisma journey by connecting with our active community. Stay informed, get involved, and collaborate with other developers:

We genuinely value your involvement and look forward to having you as part of our community!