2025年5月23日

Prisma ORM 为什么会在 Node Modules 中生成代码以及它将如何改变

Prisma ORM 历来将其数据库客户端生成到 node_modules 中。本文将解释最初这样做的原因、我们从中吸取了什么教训以及未来我们将如何改变。

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

为什么 Prisma ORM 会将 Prisma Client 代码生成到 node_modules

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

代码生成在 TypeScript 生态系统中并不是最常用的方法,而 Prisma ORM 是首批依赖它的流行库之一。为了最大程度地提高开发者的熟悉度,我们决定默认将 Prisma Client 生成到 node_modules 文件夹中,因为开发者习惯于通过这种方式在其应用程序中集成第三方库。

尽管从一开始就可以通过 output 字段为生成的代码选择自定义位置,但这种默认设置使我们在 Prisma ORM 的各种框架和使用场景中获得了统一的行为。

默认将 Prisma Client 生成到 node_modules 中,最终为大多数人带来了神奇的“它就是能用™️”的开发者体验……除非它不能用!

为什么以及我们如何在 v7 版本中改变 Prisma Client 的位置

从那时起,开发者因为 node_modules 中生成的代码而遇到了问题。JS/TS 生态系统中的许多工具都基于 node_modules 目录不会被修改(除了通过包管理器(npmpnpmyarn 等))的假设进行操作。

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

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

因为许多工具都基于 node_modules 仅由包管理器修改的假设进行操作,所以我们(以及社区中的其他人)采取了变通方法以确保流畅的开发者体验(DX)。

例如,由于 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 的开发者体验更简单、更可预测

作为这项举措的一部分,我们将移除将代码生成到 node_modules 中的选项,转而始终要求提供一个 output 路径

为了预见这一变化,我们在 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 版本中,当您未使用 prisma-client-js 生成器的自定义 output 路径时,我们在 Prisma CLI 输出中引入了以下弃用警告:

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

尽管我们预期这种引导只会带来积极影响,因为它移除了不可预测的、有问题的行为并赋予了开发者更多控制权,但许多人在看到弃用警告并切换到将 output 路径与 prisma-client-js 生成器一起使用后,实际上报告了问题。

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

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

所有这些问题都发生在使用 node_modules 中的 Prisma Client 时运行正常的项目上。为了在 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 生成器,作为使用带有 output 路径的 Prisma ORM 的默认方式。到时候,将提供详细的升级路径文档。
  • 如果您今天开始一个新项目,我们建议设置一个自定义的 output 路径,以避免打包问题并为 Prisma ORM v7 中即将到来的破坏性更改做准备。由于生成的资产(大部分)是源代码,旨在被处理并包含在您的应用程序包中,我们建议使用应用程序源代码树内的路径(例如 src/generated/prisma)。
  • 如果您在使用 output 路径时遇到问题(无论您使用的是新的 prisma-client 还是当前的 prisma-client-js 生成器),请提交一个新 issue,以便我们帮助您解决问题。

如果您有任何反馈或问题,一如既往地可以通过 X 联系我们加入我们的 Discord

不要错过下一篇文章!

订阅 Prisma 新闻邮件

© . All rights reserved.