我在将使用 Prisma 和 MongoDB 的 Next.js 项目部署到 Vercel 时遇到问题。该项目在本地运行良好,但是当我将其部署到 Vercel 时,出现以下错误:
at 8428 (/vercel/path0/.next/server/app/page.js:1:3202)
at t (/vercel/path0/.next/server/webpack-runtime.js:1:128)
at 5857 (/vercel/path0/.next/server/app/page.js:1:825)
at t (/vercel/path0/.next/server/webpack-runtime.js:1:128)
at r (/vercel/path0/.next/server/app/page.js:1:3644)
at /vercel/path0/.next/server/app/page.js:1:3682
at t.X (/vercel/path0/.next/server/webpack-runtime.js:1:1206)
at /vercel/path0/.next/server/app/page.js:1:3657
at Object.<anonymous> (/vercel/path0/.next/server/app/page.js:1:3709)
> Build error occurred
Error: Failed to collect page data for /
at /vercel/path0/node_modules/next/dist/build/utils.js:1268:15
at process.processTicksAndRejections (node:internal/process/task_queues:95:5) {
type: 'Error'
}
Error: Command "npm run build" exited with 1
向 package.json 添加了安装后脚本:
"scripts": {
"postinstall": "prisma generate"
}
确认 DATABASE_URL 在 Vercel 中设置正确。
检查了Vercel中的详细日志,但错误仍然存在。
Prisma 架构:
generator client {
provider = "prisma-client-js"
}
datasource db {
provider = "mongodb"
url = env("DATABASE_URL")
}
model Course {
id String @id @default(auto()) @map("_id") @db.ObjectId
clerkId String
name String
description String?
imageUrl String?
price Float?
isPublished Boolean @default(false)
categoryId String? @db.ObjectId
category Category? @relation(fields: [categoryId], references: [id])
attachments Attachment[]
chapters Chapter[]
purchases Purchase[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([categoryId])
}
Prisma 客户端实例化:
import { PrismaClient } from '@prisma/client';
const prismaClientSingleton = () => {
return new PrismaClient();
};
declare const globalThis: {
prismaGlobal: ReturnType<typeof prismaClientSingleton>;
} & typeof global;
const prisma = globalThis.prismaGlobal ?? prismaClientSingleton();
export default prisma;
if (process.env.NODE_ENV !== 'production') globalThis.prismaGlobal = prisma;
主页代码:
import prisma from '@/lib/prisma';
export default async function Home() {
const courses = await prisma.course.findMany({
select: {
id: true,
name: true,
},
});
return (
<main className="text-2xl">
{courses.map((course) => (
<p key={course.id}>{course.name}</p>
))}
</main>
);
}
附加信息:
该项目在本地运行得非常好。 MongoDB 连接字符串正确且可访问。 所有依赖项都是最新的。
问题:
可能导致此问题的原因是什么,如何解决该问题以成功将我的 Next.js 和 Prisma 项目与 MongoDB 部署到 Vercel?
问题似乎可能是由于与本地环境相比,Vercel 环境中 Prisma 和 MongoDB 的处理方式所致。
众所周知,Prisma 会在 Vercel 等无服务器环境中为每个请求打开一个新连接。确保您重复使用 Prisma 客户端以避免打开太多连接。您已经使用 prismaClientSingleton 完成了此操作,但请仔细检查单例模式是否正确使用。
let prisma;
if (process.env.NODE_ENV === 'production') {
prisma = new PrismaClient();
} else {
if (!global.prisma) {
global.prisma = new PrismaClient();
}
prisma = global.prisma;
}
export default prisma;
由于错误发生在构建过程中(npm run build),可能是构建过程中页面获取数据的方式有问题。 Prisma 查询(例如 findMany)可能会在构建步骤期间执行,如果当时无法访问数据库,则可能会失败。
最重要的是,在构建命令期间写入:
npx prisma generate && npm run build