Turborepo Monorepo中NestJS无法引入共享Prisma客户端的问题求助
问题
使用Turborepo构建包含NextJS、NestJS和共享Prisma客户端的Monorepo项目时,NextJS可正常使用共享Prisma客户端,但NestJS启动时报错Cannot find module '@repo/database'。
项目结构
└── turbo └── apps └── nest └── web (next) └── packages └── database (prisma) ├── schema.prisma ├── package.json ├── index.ts
database包配置
packages/database/package.json:
{ "name": "@repo/database", "version": "0.0.1", "devDependencies": { "prisma": "^5.7.1" }, "dependencies": { "@prisma/client": "^5.7.1" } }
database包导出代码
packages/database/index.ts:
import { PrismaClient } from '@prisma/client' export * from '@prisma/client'; const prismaClientSingleton = () => { return new PrismaClient() } declare global { var prisma: undefined | ReturnType<typeof prismaClientSingleton> } const prisma = globalThis.prisma ?? prismaClientSingleton() export default prisma if (process.env.NODE_ENV !== 'production') globalThis.prisma = prisma
NextJS使用示例(正常工作)
import prisma from "@repo/database"; export default async function Page() { const users= await prisma.users.findMany(); return <div> <UsersList data={(users as IUser[])}/> </div> }
NestJS配置(报错)
apps/nest/src/app.module.ts:
import {Module} from '@nestjs/common'; import {CronService} from './cron/cron.service'; import {ScheduleModule} from "@nestjs/schedule"; import {CustomPrismaModule} from 'nestjs-prisma'; import {PrismaClient} from '@repo/database'; @Module({ imports: [ScheduleModule.forRoot(), CustomPrismaModule.forRoot({ name: 'PrismaDatabase', client: new PrismaClient(), }),], providers: [CronService], }) export class AppModule { }
apps/nest/src/cron/cron.service.ts:
import {Inject, Injectable} from '@nestjs/common'; import {Cron, CronExpression} from "@nestjs/schedule"; import {CustomPrismaService} from "nestjs-prisma"; import {PrismaClient} from '@repo/database'; @Injectable() export class CronService { constructor( @Inject('PrismaDatabase') private prisma: CustomPrismaService<PrismaClient> ) {} @Cron(CronExpression.EVERY_30_SECONDS) async handleCron() { const res = await this.prisma.client.users.findMany(); console.log(res); } }
启动错误信息
"C:\Program Files\nodejs\npm.cmd" run start > your-nest-app@0.0.1 start > nest start Error: Cannot find module '@repo/database' Require stack: - C:\Workspace\xyz\turbo\apps\nest\dist\app.module.js - C:\Workspace\xyz\turbo\apps\nest\dist\main.js at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1144:15) at Function.Module._load (node:internal/modules/cjs/loader:985:27) at Module.require (node:internal/modules/cjs/loader:1235:19) at require (node:internal/modules/helpers:176:18) at Object.<anonymous> (C:\Workspace\xyz\turbo\apps\nest\src\app.module.ts:6:1) at Module._compile (node:internal/modules/cjs/loader:1376:14) at Object.Module._extensions..js (node:internal/modules/cjs/loader:1435:10) at Module.load (node:internal/modules/cjs/loader:1207:32) at Function.Module._load (node:internal/modules/cjs/loader:1023:12) at Module.require (node:internal/modules/cjs/loader:1235:19) npm ERR! Lifecycle script `start` failed with error: npm ERR! Error: command failed npm ERR! in workspace: nest@0.0.1 npm ERR! at location: C:\Workspace\xyz\turbo\apps\nest Process finished with exit code 1
解决方案
1. 完善database包的构建配置
当前database包未配置TypeScript编译,NestJS无法找到可执行的JS文件,需补充以下配置:
- 在
packages/database下创建tsconfig.json:
{ "compilerOptions": { "target": "ES2020", "module": "commonjs", "declaration": true, "outDir": "./dist", "strict": true, "esModuleInterop": true, "skipLibCheck": true, "forceConsistentCasingInFileNames": true }, "include": ["index.ts"], "exclude": ["node_modules", "dist"] }
- 修改
packages/database/package.json,添加入口、类型声明和编译脚本:
{ "name": "@repo/database", "version": "0.0.1", "main": "./dist/index.js", "types": "./dist/index.d.ts", "devDependencies": { "prisma": "^5.7.1", "typescript": "^5.3.3" }, "dependencies": { "@prisma/client": "^5.7.1" }, "scripts": { "build": "tsc", "dev": "tsc --watch" } }
2. 配置Turborepo构建依赖
在根目录turbo.json中添加构建任务规则,确保NestJS启动前先编译database包:
{ "$schema": "https://turbo.build/schema.json", "pipeline": { "build": { "dependsOn": ["^build"], "outputs": ["dist/**"] }, "dev": { "cache": false, "persistent": true } } }
3. 简化NestJS中Prisma的使用方式
无需依赖nestjs-prisma,直接导入database包的单例即可:
- 更新
apps/nest/src/app.module.ts:
import {Module} from '@nestjs/common'; import {CronService} from './cron/cron.service'; import {ScheduleModule} from "@nestjs/schedule"; import prisma from '@repo/database'; @Module({ imports: [ScheduleModule.forRoot()], providers: [ CronService, { provide: 'PRISMA_CLIENT', useValue: prisma } ], }) export class AppModule { }
- 更新
apps/nest/src/cron/cron.service.ts:
import {Inject, Injectable} from '@nestjs/common'; import {Cron, CronExpression} from "@nestjs/schedule"; import {PrismaClient} from '@repo/database'; @Injectable() export class CronService { constructor( @Inject('PRISMA_CLIENT') private prisma: PrismaClient ) {} @Cron(CronExpression.EVERY_30_SECONDS) async handleCron() { const res = await this.prisma.users.findMany(); console.log(res); } }
4. 执行构建并启动服务
- 根目录执行全量构建:
npm run build
- 或单独编译database包:
cd packages/database && npm run build
- 启动NestJS服务:
cd apps/nest && npm run start
额外注意事项
- 确保根目录
package.json的workspaces字段已包含packages/*和apps/*,保证Turborepo正确链接工作区包。 - 开发环境可启动database包的watch模式,实时同步编译结果:
cd packages/database && npm run dev
内容的提问来源于stack exchange,提问作者Arjuna Wenzel
相关产品推荐
相关产品推荐

