在 Turborepo 中使用 Prisma
Prisma (opens in a new tab) 是一个非常流行的 ORM,具有自动迁移、类型安全和集成工具。在 Turborepo 中使用它可以减少您花费在生成代码上的时间,并轻松确保您的生成的 Prisma 代码始终是最新的。
指南
本指南向您展示如何
- 在 monorepo 中设置 Prisma
- 处理迁移和代码生成脚本
- 使用 Turborepo 缓存这些脚本
- 确保它们始终在
dev
或build
运行时运行
如果您已经在数据库中设置了 Prisma,您可以跳到 步骤 4。
1. 创建您的 monorepo
如果您没有现有项目,请使用我们的 快速入门 创建一个新的 monorepo。
2. 添加一个新的 database
包
在 packages 中创建一个名为 database
的新文件夹,并在其中包含一个 package.json
{
"name": "database",
"version": "0.0.0",
"dependencies": {
"@prisma/client": "latest"
},
"devDependencies": {
// Replace "latest" with the latest version
"prisma": "latest"
}
}
如果您使用的是 pnpm
,您应该在根目录添加一个名为 .npmrc
的文件
public-hoist-pattern[]=*prisma*
运行您的包管理器的安装步骤以安装新的依赖项。
3. 运行 prisma init
cd
到 packages/database
cd packages/database
运行 npx prisma init
。
这应该在 packages/database
中创建几个文件
prisma/schema.prisma
.gitignore
.env
schema.prisma
是您的 Prisma 模式 (opens in a new tab) 所在的位置。在这里,您可以修改数据库的形状。.gitignore
将一些忽略的文件添加到 git.env
允许您手动指定您的DATABASE_URL
用于 prisma。
此时,您应该参考 Prisma 文档以了解 将您的数据库连接到 Prisma (opens in a new tab)。
连接数据库后,您可以继续。
4. 设置脚本
让我们在 packages/database
内部的 package.json
中添加一些脚本。
{
"scripts": {
"db:generate": "prisma generate",
"db:push": "prisma db push --skip-generate"
}
}
我们也需要在根目录的 turbo.json
中添加这些脚本。
{
"pipeline": {
"db:generate": {
"cache": false
},
"db:push": {
"cache": false
}
}
}
现在,我们可以从仓库根目录运行 turbo db:push db:generate
,自动迁移数据库并生成类型安全的 Prisma 客户端。
我们在 db:push
上使用 --skip-generate
标志,以确保它在迁移数据库后不会自动运行 prisma generate
。当使用 Turborepo 时,这最终会更快,因为我们自动并行化了任务。
5. 导出您的客户端
接下来,我们需要导出 @prisma/client
,以便我们可以在应用程序中使用它。让我们在 packages/database
中添加一个 index.ts
文件。
export * from '@prisma/client';
遵循 内部包模式,我们还需要在 packages/database/package.json
内部的 main
和 types
中添加 index.ts
。
{
"main": "./index.ts",
"types": "./index.ts"
}
导入 database
现在让我们将数据库包导入到我们的一个应用程序中进行测试。假设您在 apps/web
中有一个应用程序。将依赖项添加到 apps/web/package.json
{
"dependencies": {
"database": "*"
}
}
运行您的包管理器的安装命令。
现在,您可以在应用程序中的任何位置从 database
导入 PrismaClient
。
import { PrismaClient } from 'database'
const client = new PrismaClient();
您可能还需要在应用程序中进行一些配置,以允许它运行内部包。查看我们的 内部包文档 以获取更多信息。
6. 弄清楚脚本
现在我们处于一个相当不错的位置。我们有一个可重用的 database
模块,我们可以将其导入到任何应用程序中。我们有一个 turbo db:push
脚本,我们可以用来将更改推送到数据库。
但是,我们的 db:generate
脚本还没有优化。它们为我们的 dev
和 build
任务提供了重要的代码。如果新开发人员在没有先运行 db:generate
的情况下,在应用程序上运行 dev
,他们会遇到错误。
因此,让我们确保在用户运行 dev
之前,始终运行 db:generate
。
{
"pipeline": {
"dev": {
"dependsOn": ["^db:generate"],
"cache": false
},
"build": {
"dependsOn": ["^db:generate"],
"outputs": ["your-outputs-here"]
},
"db:generate": {
"cache": false
}
}
}
查看有关 运行任务 的部分,以了解有关 ^db:generate
语法的更多信息。
7. 缓存 prisma generate
的结果
prisma generate
将文件输出到文件系统,通常在 node_modules
内。理论上,应该可以使用 Turborepo 缓存 prisma generate
的输出,以节省几秒钟。
但是,Prisma 在不同的包管理器中表现不同。这会导致不可预测的结果,这可能会导致某些情况下部署失败。我们建议不要缓存 prisma generate
的结果,而不是记录每种方法的复杂性。由于 prisma generate
通常只需要 5-6 秒,并且在较大的 schema
文件中也不会花费更长时间,这似乎是一个不错的权衡。
您可能希望自己尝试一下。如果您发现一个您认为有效的解决方案,请随时 添加一个问题 (在新标签页中打开),我们可以更新此部分。
- 进入生产环境
现在您已经走到了这一步,您已准备好部署您的应用程序。根据您的数据库所在位置,您需要根据数据库设置的文档设计您的部署管道。从这一点开始,需要考虑很多因素,因此我们无法提供一个万能的解决方案。您可能需要访问数据库及其部署平台的文档以了解更多信息。