在 nuxtjs 中使用 prisma 时,遇到了许多问题,有的与 nuxtjs 有关,有的与它无关。最终还是找到了让 prisma 正常工作的办法。

我遇到的问题

  • 在 nuxtjs 中使用 prisma, 开发模式正常工作,但是构建失败,或者构建成功,运行构建结果失败。
  • Invalid module ".prisma/client/index-browser" is not a valid package name.
  • FATAL ERROR: Reached heap limit Allocation failed - JavaScript heap out of memory.
  • nitro 23:49:44 ERROR TypeError ERR_INVALID_MODULE_SPECIFIER: Invalid module ".prisma" is not a valid package name.
  • Error validating datasource db: the URL must start with the protocol prisma://.
  • __dirname is not defined in es module scope.
  • Table Doesn’t Exist in Database.

解决办法

  1. 放弃使用@prisma/nuxt。此时的版本是@prisma/nuxt@0.3.0, prisma@6.7.0.
  2. 安装依赖:npm install prisma @prisma/client.
  3. prisma 文件夹放在项目根目录,prisma/schema.prisma 文件里的关键配置:
    generator client {
      provider = "prisma-client-js"
      output   = "../node_modules/_db"
    }
    

    output官方建议配置,prisma7 必须配置。此时保持默认配置在 linux 上正常工作,在 Windows 不能。并且就复制我的 output,不要修改,如果生成目录在 node_modules 之外,又会产生其他错误。
  4. package.json 添加如下命令,用来快速操作 prisma。
    "scripts": {
     "prisma:reset": "prisma migrate reset",
     "prisma:migrate": "prisma migrate dev",
     "prisma:generate": "prisma generate"
    }
    

    每次修改 prisma/schema.prisma 后需要调用 npm run prisma:generate 生成 ../node_modules/_db.
  5. 创建一个文件导出 prisma 单例,不需要单例可以跳过。我创建的是 server/utils/db.ts
    import { PrismaClient } from "_db";
    export * from "_db";
    
    const prismaClientSingleton = () => {
      return new PrismaClient();
    };
    
    declare const globalThis: {
      prismaGlobal: ReturnType<typeof prismaClientSingleton>;
    } & typeof global;
    
    export const prisma = globalThis.prismaGlobal ?? prismaClientSingleton();
    if (process.env.NODE_ENV !== "production") globalThis.prismaGlobal = prisma;
    
  6. 如何引用:
    • 引用单例:import { prisma } from "~/server/utils/db"
    • typescript 引用类型:import { User, Post } from "~/server/utils/db"
    • 如果你没有创建server/utils/db,可以这样写: import { PrismaClient } from "_db"
  7. 其他:
    • 使用 sqlite 时,建议数据库路径使用绝对路径,以免构建后找不到数据库文件。
    • 使用 npm, pnpm 都可以,其他的我没有尝试。