Skip to main content

如何在 pnpm 工作区 monorepo 中使用 Prisma ORM

10 min

Prisma 是一款功能强大的数据库对象关系映射 (ORM),可管理你的数据库。与 pnpm 工作区 结合使用,你可以维护精简且模块化的单一存储库架构。在本指南中,我们将介绍如何在 pnpm Workspaces monorepo 中将 Prisma 设置为其自己的包,从而实现跨应用的可维护类型共享和高效的数据库管理。

¥Prisma is a powerful ORM for managing your database, and when combined with pnpm Workspaces, you can maintain a lean and modular monorepo architecture. In this guide, we’ll walk through setting up Prisma in its own package within a pnpm Workspaces monorepo, enabling maintainable type sharing and efficient database management across your apps.

你将学习的内容:

¥What you'll learn:

  • 如何使用 pnpm Workspaces 初始化 monorepo。

    ¥How to initialize a monorepo using pnpm Workspaces.

  • 将 Prisma 集成为独立包的步骤。

    ¥Steps to integrate Prisma as a standalone package.

  • 如何生成 Prisma 客户端并在不同包之间共享。

    ¥How to generate and share the Prisma Client across packages.

  • 将 Prisma 包集成到工作区中的应用中。

    ¥Integrating the Prisma package into an application within your workspace.

1. 准备项目并配置 pnpm 工作区

¥ Prepare your project and configure pnpm workspaces

在集成 Prisma 之前,你需要设置你的项目结构。首先为你的项目创建一个新目录(例如 my-monorepo)并初始化一个 Node.js 项目:

¥Before integrating Prisma, you need to set up your project structure. Start by creating a new directory for your project (for example, my-monorepo) and initialize a Node.js project:

mkdir my-monorepo
cd my-monorepo
pnpm init

接下来,创建一个 pnpm-workspace.yaml 文件来定义你的工作区结构并固定 Prisma 版本:

¥Next, create a pnpm-workspace.yaml file to define your workspace structure and pin the Prisma version:

touch pnpm-workspace.yaml

将以下配置添加到 pnpm-workspace.yaml

¥Add the following configuration to pnpm-workspace.yaml:

pnpm-workspace.yaml
packages:
- "apps/*"
- "packages/*"
catalogs:
prisma:
prisma: latest
注意

catalogs 帮助你在各个代码库中固定 Prisma 的某个版本。你可以通过 此处 了解更多关于它们的信息。在 pnpm-workspace.yaml 文件中明确固定 prisma 的最新版本。本文撰写时,版本为 6.3.1

¥The catalogs help you pin a certain version of prisma across your repositories. You can learn more about them here. Explictly pin the lastest version of prisma in the pnpm-workspace.yaml file. At the time of writing, this is version 6.3.1.

最后,为你的应用和共享包创建目录:

¥Finally, create directories for your applications and shared packages:

mkdir apps
mkdir -p packages/database

2. 设置共享数据库包

¥ Setup the shared database package

本节介绍如何创建使用 Prisma 的独立数据库包。该软件包将包含所有数据库模型和生成的 Prisma 客户端,使其可在你的 monorepo 中重复使用。

¥This section covers creating a standalone database package that uses Prisma. The package will house all database models and the generated Prisma Client, making it reusable across your monorepo.

2.1.初始化软件包并安装依赖

¥2.1. Initialize the package and install dependencies

进入 packages/database 目录并初始化一个新包:

¥Navigate to the packages/database directory and initialize a new package:

cd packages/database
pnpm init

使用固定的 catalog 将 Prisma 添加为 package.json 中的开发依赖:

¥Add Prisma as a development dependency in your package.json using the pinned catalog:

database/package.json
"devDependencies": {
"prisma": "catalog:prisma"
}

然后安装 Prisma:

¥Then install Prisma:

pnpm install

然后,添加其他依赖:

¥Then, add additional dependencies:

pnpm add typescript tsx @types/node -D

然后安装使用 Prisma Postgres 所需的 Prisma 客户端扩展:

¥Then install the Prisma Client extension required to use Prisma Postgres:

pnpm add @prisma/extension-accelerate
信息

本指南使用 Prisma Postgres。如果你计划使用其他数据库,则可以省略 @prisma/extension-accelerate package

¥This guide uses Prisma Postgres. If you plan to use a different database, you can omit the @prisma/extension-accelerate package.

为你的 database 包初始化一个 tsconfig.json 文件:

¥Initalize a tsconfig.json file for your database package:

pnpm tsc --init

2.2.在数据库包中设置 Prisma ORM

¥2.2. Setup Prisma ORM in your database package

运行以下命令,使用 database 包中的 Prisma Postgres 实例初始化 Prisma ORM:

¥Initialize Prisma ORM with an instance of Prisma Postgres in the database package by running the following command:

pnpm prisma init --db

输入项目名称并选择数据库区域。

¥Enter a name for your project and choose a database region.

信息

在本指南中,我们将使用 Prisma Postgres。如果你不使用 Prisma Postgres 数据库,则不需要添加 --db 标志。

¥We're going to be using Prisma Postgres in this guide. If you're not using a Prisma Postgres database, you won't need to add the --db flag.

这个命令:

¥This command:

  • 将你的 CLI 连接到你的 账户。如果你未登录或没有账户,你的浏览器将打开以指导你创建新账户或登录现有账户。

    ¥Connects your CLI to your account. If you're not logged in or don't have an account, your browser will open to guide you through creating a new account or signing into your existing one.

  • 为你的数据库模型创建一个包含 schema.prisma 文件的 prisma 目录。

    ¥Creates a prisma directory containing a schema.prisma file for your database models.

  • 使用你的 DATABASE_URL 创建 .env 文件(例如,对于 Prisma Postgres,它应该具有类似于 DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/?api_key=eyJhbGciOiJIUzI..." 的内容)。

    ¥Creates a .env file with your DATABASE_URL (e.g., for Prisma Postgres it should have something similar to DATABASE_URL="prisma+postgres://accelerate.prisma-data.net/?api_key=eyJhbGciOiJIUzI...").

编辑 schema.prisma 文件以在数据库中定义 User 模型,并指定 自定义 output 目录 来生成 Prisma 客户端。这可确保生成的类型得到正确解析:

¥Edit the schema.prisma file to define a User model in your database and specify a custom output directory to generate the Prisma Client. This ensures that generated types are resolved correctly:

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

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

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

接下来,向你的 package.json 添加辅助脚本以简化 Prisma 命令:

¥Next, add helper scripts to your package.json to simplify Prisma commands:

database/package.json
{
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"db:generate": "prisma generate --no-engine",
"db:migrate": "prisma migrate dev",
"db:deploy": "prisma migrate deploy",
"db:studio": "prisma studio"
}
}
信息

如果你不使用 Prisma Postgres 作为数据库,请从 db:generate 脚本中排除 --no-engine 标志。

¥If you're not using Prisma Postgres for your database, exclude the --no-engine flag from the db:generate script.

使用 Prisma 迁移 迁移数据库更改:

¥Use Prisma Migrate to migrate your database changes:

pnpm run db:migrate

当 CLI 提示时,请输入迁移的描述性名称。

¥When prompted by the CLI, enter a descriptive name for your migration.

迁移成功后,创建一个 client.ts 文件,使用 Accelerate 扩展初始化 Prisma 客户端:

¥Once the migration is successful, create a client.ts file to initialize Prisma Client with the Accelerate extension:

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

// Instantiate the extended Prisma client to infer its type
const extendedPrisma = new PrismaClient().$extends(withAccelerate());
type ExtendedPrismaClient = typeof extendedPrisma;

// Use globalThis for broader environment compatibility
const globalForPrisma = globalThis as typeof globalThis & {
prisma?: ExtendedPrismaClient;
};

// Named export with global memoization
export const prisma: ExtendedPrismaClient =
globalForPrisma.prisma ?? extendedPrisma;

if (process.env.NODE_ENV !== "production") {
globalForPrisma.prisma = prisma;
}
信息

如果你不使用 Prisma Postgres 作为数据库,请从其后一行中排除 import { withAccelerate } 行和 .$extends(withAccelerate()) 行。

¥If you're not using Prisma Postgres for your database, exclude the import { withAccelerate } line and .$extends(withAccelerate()) from the line following it.

然后,创建一个 index.ts 文件以重新导出 Prisma 客户端实例和所有生成的类型:

¥Then, create an index.ts file to re-export the instance of Prisma Client and all generated types:

database/index.ts
export { prisma } from "./client";
export * from "./generated/client";

此时,你的共享数据库包已完全配置,可以在你的 monorepo 中使用。

¥At this point, your shared database package is fully configured and ready for use across your monorepo.

3. 设置并集成前端应用

¥ Set up and integrate your frontend application

现在数据库包已设置完毕,请创建一个前端应用(使用 Next.js),该应用使用共享的 Prisma 客户端与你的数据库交互。

¥Now that the database package is set up, create a frontend application (using Next.js) that uses the shared Prisma Client to interact with your database.

3.1.引导 Next.js 应用

¥3.1. Bootstrap a Next.js application

进入 apps 目录:

¥Navigate to the apps directory:

cd ../../apps

创建一个名为 web 的新 Next.js 应用:

¥Create a new Next.js app named web:

pnpm create next-app@latest web --yes
重要

--yes 标志使用默认配置来引导 Next.js 应用(本指南中使用不带 src/ 目录的应用路由,并使用 pnpm 作为安装程序)。

¥The --yes flag uses default configurations to bootstrap the Next.js app (which in this guide uses the app router without a src/ directory and pnpm as the installer).

此外,该标志可能会自动在 web 文件夹中初始化一个 Git 存储库。如果发生这种情况,请运行 rm -r .git 删除 .git 目录。

¥Additionally, the flag may automatically initialize a Git repository in the web folder. If that happens, please remove the .git directory by running rm -r .git.

然后,导航到 Web 目录:

¥Then, navigate into the web directory:

cd web/

从数据库包中复制 .env 文件,以确保相同的环境变量可用:

¥Copy the .env file from the database package to ensure the same environment variables are available:

cp ../../packages/database/.env .

打开 Next.js 应用的 package.json 文件,并将共享的 database 包添加为依赖:

¥Open the package.json file of your Next.js app and add the shared database package as a dependency:

web/package.json
"dependencies": {
"database": "workspace:*",
// additional dependencies
// ...
}

运行以下命令,安装 database 包:

¥Run the following command to install the database package:

pnpm install

3.2.在应用代码中集成共享的 database

¥3.2. Integrate the shared database package in your app code

修改 Next.js 应用代码,使其使用数据库包中的 Prisma 客户端。按如下方式更新 app/page.tsx

¥Modify your Next.js application code to use Prisma Client from the database package. Update app/page.tsx as follows:

app/page.tsx
import { prisma } from "database";

export default async function Home() {
const user = await prisma.user.findFirst({
select: {
name: true
}
})

return (
<div>
{user?.name && <p>Hello from {user.name}</p>}
{!user?.name && <p>No user has been added to the database yet. </p>}
</div>
);
}

此代码演示了如何导入和使用共享 Prisma 客户端来查询你的 User 模型。

¥This code demonstrates importing and using the shared Prisma Client to query your User model.

3.3.添加辅助脚本并运行应用

¥3.3. Add helper scripts and run your application

将以下脚本添加到 monorepo 的根目录 package.json 中。它们确保数据库迁移、类型生成和应用构建按正确的顺序运行:

¥Add the following scripts to the root package.json of your monorepo. They ensure that database migrations, type generation, and app builds run in the proper order:

"scripts": {
"build": "pnpm --filter database db:deploy && pnpm --filter database db:generate && pnpm --filter web build",
"start": "pnpm --filter web start",
"dev": "pnpm --filter database db:generate && pnpm --filter web dev",
"studio": "pnpm --filter database db:studio"
}

3.4.运行你的应用

¥3.4. Run your application

然后返回到 monorepo 的根目录:

¥Then head back to the root of the monorepo:

cd ../../

通过执行以下命令启动你的开发服务器:

¥Start your development server by executing:

pnpm run dev

在浏览器中打开 http://localhost:3000 以查看应用的运行情况。

¥Open your browser at http://localhost:3000 to see your app in action.

3.5.(可选的)使用 Prisma Studio 将数据添加到数据库

¥3.5. (Optional) Add data to your database using Prisma Studio

你的数据库中目前应该还没有数据。你可以在 CLI 中执行 pnpm run studio,以在 http://localhost:5555 中启动 Prisma 工作室,从而与你的数据库交互并向其中添加数据。

¥There shouldn't be data in your database yet. You can execute pnpm run studio in your CLI to start a Prisma Studio in http://localhost:5555 to interact with your database and add data to it.

后续步骤

¥Next Steps

你现在已经创建了一个有效使用 Prisma ORM 的 monorepo,并将共享数据库包集成到 Next.js 应用中。

¥You have now created a monorepo that uses Prisma ORM effectively, with a shared database package integrated into a Next.js application.

如需进一步探索并增强你的设置,请考虑阅读 如何在 Turborepo 中使用 Prisma ORM 指南。

¥For further exploration and to enhance your setup, consider reading the How to use Prisma ORM with Turborepo guide.


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!