跳到主要内容

Vercel 构建依赖缓存解决方法

问题

如果您使用 Prisma ORM 将应用程序部署到 Vercel,您可能会在部署时遇到以下错误消息

Prisma has detected that this project was built on Vercel, which caches dependencies.
This leads to an outdated Prisma Client because Prisma's auto-generation isn't triggered.
To fix this, make sure to run the `prisma generate` command during the build process.

Learn how: https://pris.ly/d/vercel-build

发生这种情况是因为 Vercel 会缓存项目的依赖项,直到其中一个依赖项发生更改。这样做是为了加快构建速度,虽然这通常是一件好事,但它会给 Prisma Client 带来一些问题。

Prisma ORM 使用 postinstall 钩子在安装依赖项时生成 Prisma Client。由于 Vercel 使用缓存的模块,因此在初始部署之后的后续部署中永远不会运行此 postinstall 钩子。这导致 Prisma Client 与您的数据库架构不同步。

此错误消息阻止这种情况发生,并引导您在此处了解如何修复根本问题。

低于 4.13.0 版本的 Prisma Client

在低于 4.13.0 版本的 Prisma Client 上,您可能会遇到如下所示的错误消息

// 1: When adding a field:
Unknown arg `name` in data.name for type UserCreateInput. Did you mean `nick`?

// 2: When removing a field:
Invalid `prisma.user.create()` invocation: The column `User.name` does not exist in the current database.

// 3: When a model was removed/renamed
Invalid `prisma.user.deleteMany()` invocation: The table `public.User` does not exist in the current database.

// 4: When a model was added
Cannot read properties of undefined (reading 'create')

本指南中描述的解决方案旨在解决这些问题。

解决方案

可以通过在每次部署时显式生成 Prisma Client 来解决此问题。在每次部署之前运行 prisma generate 将确保 Prisma Client 是最新的。

您可以配置部署以通过多种不同的方式运行此命令

自定义 postinstall 脚本

信息

这是首选方法,因为它是一种通用的解决方案。

在项目 package.json 文件的 scripts 部分中,如果尚没有名为 postinstall 的脚本,请添加一个并将 prisma generate 添加到该脚本

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

应用程序的 build 脚本在 package.json

在项目 package.json 文件的 scripts 部分中,在 build 脚本中,将 prisma generate 前置到默认的 vercel build 命令

{
...
"scripts" {
"build": "prisma generate && <actual-build-command>"
}
...
}

Vercel UI 的构建脚本字段

配置 prisma generate 在每次部署时运行的另一种方法是将命令添加到通过 Vercel UI 的构建设置中。

在您的项目仪表板中,转到 Settings 选项卡并找到 General 部分。在该部分中,您将找到一个标记为 Build & Development Settings 的框,其中包含一个名为 Build Command 的输入字段

Vercel project dashboard&#39;s Build Command setting

在该字段中,将 prisma generate 前置到现有脚本

Vercel project dashboard&#39;s Build Command setting filled