You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Next.js15+Auth.js+Prisma在Vercel部署的Edge Runtime兼容问题

解决Vercel部署中Auth.js v5 + Prisma Adapter的Runtime不兼容问题

问题原因

Auth.js v5 默认在Edge Runtime环境下运行其认证路由和回调,但Prisma Client依赖Node.js Runtime的系统级二进制文件(查询引擎),无法在Edge环境中加载,这直接导致了你遇到的PrismaClientInitializationError——找不到对应rhel-openssl-3.0.x环境的查询引擎。

核心解决方案:强制Auth.js使用Node.js Runtime

1. 为Auth路由指定Node.js Runtime

在apps/web/app/api/auth/[...nextauth]/route.ts中添加Runtime声明:

export { GET, POST } from "@repo/authjs-core";
// 强制该路由使用Node.js Runtime
export const runtime = "nodejs";

2. 调整Next.js配置适配Monorepo + Prisma

修改next.config.mjs,优化Prisma的打包处理:

import { PrismaPlugin } from "@prisma/nextjs-monorepo-workaround-plugin";

const nextConfig = {
  serverExternalPackages: ["@prisma/client", "prisma"],
  webpack: (config, { isServer }) => {
    if (isServer) {
      config.plugins = [...config.plugins, new PrismaPlugin()];
    }
    // 避免webpack打包Prisma引擎文件
    config.externals.push({
      "@prisma/client": "commonjs @prisma/client",
    });
    return config;
  },
  // 仅转译authjs-core,Prisma相关包无需转译
  transpilePackages: ["@repo/authjs-core"],
};

export default nextConfig;

3. 确保Prisma引擎正确生成

在项目根目录package.json中添加构建前置命令,保证Vercel构建时生成对应环境的引擎:

{
  "scripts": {
    "build": "prisma generate && turbo build"
  }
}

同时在@repo/database的package.json中添加依赖安装后的自动生成:

{
  "scripts": {
    "postinstall": "prisma generate"
  }
}

4. 修正Prisma Client导入路径

调整@repo/database/src/index.ts的导入逻辑,直接从生成的客户端导入:

import { PrismaClient, PrismaClientOptions } from "../generated/client";

export function createPrismaClient(options?: PrismaClientOptions): PrismaClient {
  const clientConfig: Prisma.PrismaClientOptions = {};

  if (options?.connectionString) {
    clientConfig.datasources = {
      db: {
        url: options.connectionString
      }
    };
  }

  return new PrismaClient(clientConfig);
}

const defaultOptions: PrismaClientOptions = {
  connectionString: process.env.DATABASE_URL
};

const prismaClientSingleton = () => createPrismaClient(defaultOptions);

declare const globalThis: {
  prismaGlobal: ReturnType<typeof prismaClientSingleton>;
} & typeof global;

const prisma = globalThis.prismaGlobal ?? prismaClientSingleton();

export { prisma };

if (process.env.NODE_ENV !== "production") globalThis.prismaGlobal = prisma;

export * from "../generated/client";

替代方案:分离Prisma操作到独立API路由

如果上述配置仍有问题,可将Auth.js回调中的Prisma操作移到单独的Node.js Runtime路由:

  1. 创建apps/web/app/api/auth/user/route.ts:
import { prisma } from "@repo/database";
import { NextResponse } from "next/server";

export const runtime = "nodejs";

export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const userId = searchParams.get("id");
  if (!userId) return NextResponse.json({ error: "Missing user ID" }, { status: 400 });
  
  const user = await prisma.user.findUnique({ where: { id: userId } });
  return NextResponse.json(user);
}
  1. 在Auth.js的回调中调用该API:
async authorize(credentials) {
  // 替换原Prisma调用为API请求
  const res = await fetch(`${process.env.NEXT_PUBLIC_APP_URL}/api/auth/user?id=${userId}`);
  const user = await res.json();
  return user;
}

额外检查项

  • 确认Vercel环境变量DATABASE_URL正确指向Supabase PostgreSQL地址
  • 保持schema.prisma中binaryTargets包含rhel-openssl-3.0.x配置
  • 避免在Edge Runtime组件中直接导入@repo/database,所有Prisma操作仅在Node.js Runtime路由/Server Components中执行

内容的提问来源于stack exchange,提问作者Michal Masar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 01:00:54