2025 年 5 月 23 日

为什么 Prisma ORM 将代码生成到 Node 模块中,以及它为何将改变

Prisma ORM 历史上将其数据库客户端代码生成到 node_modules。但它为什么这样做?让我们来看看这个决定是如何做出的,以及我们将来为何要改变它。

Why Prisma ORM Generates Code into Node Modules & Why It’ll Change

自首次发布以来,Prisma ORM 一直使用代码生成来生成一个根据数据库 schema 定制的数据库客户端(称为“Prisma Client”)。Prisma Client 库根据 Prisma schema 自动生成,以便它了解其结构并能为其提供自定义的、类型安全的查询。

代码生成在 TypeScript 生态系统中并不是最传统的方法,Prisma ORM 是首批依赖它的流行库之一。为了让开发者感到熟悉,我们决定默认将 Prisma Client 生成到 node_modules 文件夹中,因为开发者通常就是这样将第三方库集成到他们的应用程序中的。

虽然从一开始就可以通过 output 字段为生成的代码选择自定义位置,但这个默认设置使我们在 Prisma ORM 的各种框架和使用上下文中保持了统一的行为。

默认将 Prisma Client 生成到 node_modules 最终为大多数人带来了神奇的“开箱即用™️”的开发者体验……除了,当它不起作用的时候!

我们为何以及如何改变 v7 中 Prisma Client 的位置

此后,开发者由于 node_modules 中生成的代码遇到了问题。JS/TS 生态系统中的许多工具都假定 node_modules 目录不会被修改——除了由你的包管理器(npm, pnpm, yarn 等)修改。

然而,使用 Prisma ORM,你需要在每次数据库 schema 更改后重新生成 Prisma Client,以便生成的代码反映数据库的最新状态。这个要求加上将生成的代码放入 node_modules 的默认选择,违反了生态系统中许多工具的假设。

将生成的代码放入 node_modules 时所需的变通方法

因为许多工具都假设 node_modules 只会被包管理器修改,我们(以及社区中的其他人)采取了变通方法以确保流畅的开发体验。

例如,由于 TS 语言服务器不监视 node_modules 中的更改,我们调整了 Prisma VS Code 扩展,以便每当你运行 prisma generate 时都会重新启动 TS 语言服务器。另一个例子是 @prisma/nextjs-monorepo-workaround-plugin 包,其唯一目的是确保当 Prisma ORM 在使用 Next.js 的 monorepos 中时,文件能够从 node_modules 正确复制。

针对生成的代码存在于 node_modules 这一核心问题的变通方法以各种形式存在,从专门的包到硬编码的代码路径。

未来将有何变化?

虽然最初决定将 Prisma Client 生成到 node_modules 帮助许多开发者入门并提供了流畅、统一的开发体验,但我们也看到这种“神奇”的行为在开发者使用 Prisma ORM 时经常导致意想不到的问题。

我们目前正在通过消除神奇行为或不必要的抽象层,使使用 Prisma ORM 的开发体验更简单、更可预测

作为这项举措的一部分,我们将通过始终要求指定 output 路径来移除将代码生成到 node_modules 的选项

为了预见这一变化,我们在 v6.6.0 中添加了弃用警告并更改了我们的文档。这在社区中引起了一些不必要的困惑,请在下一节阅读更多相关内容。

这一改变将在今年晚些时候作为 Prisma ORM v7 的一部分发布,并且只影响新的 prisma-client 生成器。这种方法有几个优点:

  • 生成的代码将被视为“常规”应用程序代码:开发者将拥有对其的完全控制权,并可以决定它如何成为其应用程序捆绑包的一部分。
  • 由于神奇行为而带来的更强的可预测性,不再需要变通方法。
  • 符合 node_modules 只能由包管理器修改的假设。

prisma-clientprisma-client-js 生成器

如果你关注了我们的发布,你会知道我们在 v6.6.0 中发布了一个新生成器,简称 prisma-client

这个新生成器支持 ESM,兼容各种 JS 运行时,总体上更灵活,并且要求自定义 output 路径。

在 Prisma ORM v7 中,它将成为与 Prisma ORM 一起使用的默认生成器,而当前的 prisma-client-js 生成器(带有神奇的 node_modules 生成)将进入维护模式。

v6.6.0 以来设置 output 路径的困惑

为了预见 v7 中即将到来的变化,我们希望通过促使开发者不再依赖将 Prisma Client 生成到 node_modules 来帮助他们为强制 output 路径的重大变更做准备。

因此,在最近的 v6.6.0 发布中,当你不使用自定义 output 路径与 prisma-client-js 生成器时,我们在 Prisma CLI 输出中引入了以下弃用警告:

我们还更改了运行 prisma init 时生成的默认 Prisma schema,使其包含 output 路径,并相应更新了我们的文档。

虽然我们期望这种推动只会带来积极影响,因为它消除了不可预测的、有问题行为,并给予开发者更多控制,但很多人实际上在看到弃用警告并切换到将自定义 output 路径与 prisma-client-js 生成器一起使用后报告了问题。

用户开始报告 src/generated/prisma 中的 linting 失败,这在例如 Next.js 开发服务器等工具中尤为突出,因为如果检测到 linting 错误,它会停止操作。由于代码是生成的,linting 错误实际上并不重要,但用户默认并没有将 src/generated 从他们的 linting 配置中排除。

其他用户报告了他们的打包工具、相对路径解析以及许多其他意外副作用的问题。总的来说,我们看到了关于在哪里生成 Prisma Client 以及如何打包它的许多困惑。

所有这一切都发生在 Prisma Client 存在于 node_modules 中时运行良好的项目中。为了在 v7 之前避免这些问题,我们再次从 CLI 输出中移除了弃用警告,并将修复社区提出的问题。

今天何时使用 Prisma ORM 的自定义 output 路径

以下是这一切对你今天意味着什么的简要概括:

  • 如果你有一个现有的 Prisma ORM 项目并正在使用 prisma-client-js 生成器:
    • 如果你最近添加了自定义 output 路径并因此看到了错误,你可以像以前一样恢复将 Prisma Client 生成到 node_modules 中。
    • 如果 Prisma ORM 在将 Prisma Client 生成到 node_modules 时对你来说运行良好,则没有理由更改任何内容。Prisma ORM v7 将引入新的 prisma-client 生成器作为使用 Prisma ORM 并带有 output 路径的默认方式。届时,将会有全面的文档说明你的升级路径。
  • 如果你今天开始一个新项目,我们建议设置一个自定义 output 路径,以避免捆绑问题并为 Prisma ORM v7 中即将到来的重大更改做准备。由于生成的资产(大部分)是源代码,旨在被处理并包含在你的应用程序的捆绑包中,我们建议使用应用程序源代码树内的路径(例如 src/generated/prisma)。
  • 如果你在使用 output 路径时遇到问题(无论你使用新的 prisma-client 还是当前的 prisma-client-js 生成器),请打开一个新 issue,以便我们帮助你解决问题。

一如既往,如果你有任何反馈或问题,请在 X 上联系我们加入我们的 Discord

不要错过下一篇文章!

订阅 Prisma 新闻通讯

© . This site is unofficial and not affiliated with Prisma Data, Inc.