如何在 Turborepo 中使用 Prisma ORM
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:
- npm
- yarn
- pnpm
cd turborepo-prisma
npm install turbo --save-dev
cd turborepo-prisma
yarn add turbo --dev --ignore-workspace-root-check
cd turborepo-prisma
pnpm add turbo --save-dev --ignore-workspace-root-check
有关安装 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:
{
"name": "@repo/db",
"version": "0.0.0"
}
接下来,安装使用 Prisma ORM 所需的依赖。使用你首选的软件包管理器:
¥Next, install the required dependencies to use Prisma ORM. Use your preferred package manager:
- 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
如果使用 Prisma Postgres,请安装 @prisma/extension-accelerate
包:
¥If using Prisma Postgres, install the @prisma/extension-accelerate
package:
- npm
- yarn
- pnpm
npm install @prisma/extension-accelerate
yarn add @prisma/extension-accelerate
pnpm add @prisma/extension-accelerate
2.2.初始化 Prisma 并定义模型
¥2.2. Initialize Prisma and define models
在 database
目录中,运行以下命令初始化 Prisma:
¥Inside the database
directory, initialize prisma by running:
- npm
- yarn
- pnpm
npx prisma init --db --output ../generated/prisma
yarn prisma init --db --output ../generated/prisma
pnpm prisma init --db --output ../generated/prisma
这将在 packages/database
中创建多个文件:
¥This will create several files inside packages/database
:
-
一个包含
schema.prisma
文件的prisma
目录。¥A
prisma
directory with aschema.prisma
file. -
一个 Prisma Postgres 数据库。
¥A Prisma Postgres database.
-
一个位于项目根目录、包含
DATABASE_URL
文件的.env
文件。¥A
.env
file containing theDATABASE_URL
at the project root. -
用于生成的 Prisma 客户端的
output
目录,用作generated/prisma
。¥An
output
directory for the generated Prisma Client asgenerated/prisma
.
在 packages/database/prisma/schema.prisma
文件中,添加以下模型:
¥In the packages/database/prisma/schema.prisma
file, add the following models:
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
:
{
"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:
{
"$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:
- npm
- yarn
- pnpm
npx turbo db:migrate
yarn turbo db:migrate
pnpm turbo db:migrate
生成你的 prisma.schema
¥Generate your prisma.schema
要从 Prisma 模式生成类型,请从项目根目录运行:
¥To generate the types from Prisma schema, from the project root run:
- npm
- yarn
- pnpm
npx turbo db:generate
yarn turbo db:generate
pnpm 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
:
- Prisma Postgres (recommended)
- Other databases
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;
import { PrismaClient } from "../generated/prisma";
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
实例:
¥Then create an index.ts
file in the src
folder to re-export the generated prisma types and the PrismaClient
instance:
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.
{
"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
:
- npm
- yarn
- pnpm
{
// ...
"dependencies": {
"@repo/db": "*"
// ...
}
// ...
}
{
// ...
"dependencies": {
"@repo/db": "*"
// ...
}
// ...
}
{
// ...
"dependencies": {
"@repo/db": "workspace:*"
// ...
}
// ...
}
在 apps/web
目录中运行包管理器的安装命令:
¥Run your package manager's install command inside the apps/web
directory:
- npm
- yarn
- pnpm
cd apps/web
npm install
cd apps/web
yarn install
cd apps/web
pnpm 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:
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
:
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:generate
和 db:deploy
脚本尚未针对 monorepo 设置进行优化,但对于 dev
和 build
任务至关重要。
¥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.
为防止这种情况,请确保始终在运行 dev
或 build
之前执行 db:generate
。此外,请确保 db:deploy
和 db: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:
{
"$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
"script":{
"dev": "next dev --port 3000",
}
然后从项目根目录运行项目:
¥Then from the project root run the project:
- npm
- yarn
- pnpm
npx turbo run dev --filter=web
yarn turbo run dev --filter=web
pnpm 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:
- npm
- yarn
- pnpm
npx prisma studio
yarn prisma studio
pnpm 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:
- Follow us on X for announcements, live events and useful tips.
- Join our Discord to ask questions, talk to the community, and get active support through conversations.
- Subscribe on YouTube for tutorials, demos, and streams.
- Engage on GitHub by starring the repository, reporting issues, or contributing to an issue.