跳到主要內容

如何搭配 Turborepo 使用 Prisma ORM

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

讓我們從 page.tsx 檔案中 web 應用程式的 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,他們將會遇到錯誤。

為了防止這種情況,請確保 db:generate 始終在執行 devbuild 之前執行。此外,請確保在 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 設定!