Netlify 构建依赖缓存解决方法
问题
¥Problem
如果你使用 Prisma ORM 将应用部署到 Netlify,你可能会在部署时遇到以下错误消息:
¥If you deploy an application using Prisma ORM to Netlify, you may run into the following error message on deployment:
Prisma has detected that this project was built on Netlify, 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/netlify-build
发生这种情况是因为 Netlify 会缓存项目的依赖,直到这些依赖之一发生更改。这样做是为了允许更快的构建,虽然这通常是一件好事,但它会给 Prisma Client 带来一些问题。
¥This occurs because Netlify caches the dependencies of your project until one of those dependencies changes. It does this to allow faster builds, and while this is typically a good thing, it causes some problems for Prisma Client.
当安装依赖时,Prisma ORM 使用 postinstall
钩子生成 Prisma 客户端。由于 Netlify 使用缓存模块,因此在初始部署后的后续部署中永远不会运行此 postinstall
钩子。这会导致 Prisma 客户端与你的数据库架构不同步。
¥Prisma ORM uses a postinstall
hook to generate Prisma Client when dependencies are installed. Because Netlify uses cached modules, this postinstall
hook never gets run in subsequent deployments after the initial deployment. This results in Prisma Client becoming out of sync with your database schema.
此错误消息可防止这种情况发生,并指导你在此处了解如何解决根本问题。
¥This error message prevents this situation from happening and directs you here to learn how to fix the root issue.
Prisma Client versions below 4.13.0
在低于 4.13.0 的 Prisma 客户端版本上,你可能会遇到如下所示的错误消息:
¥On Prisma Client versions lower than 4.13.0, you may encounter error messages that look like the following:
// 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')
本指南中描述的解决方案旨在解决这些问题。
¥The solutions described in this guide are meant to solve these problems.
解决方案
¥Solution
这个问题可以通过在每次部署时显式生成 Prisma 客户端来解决。每次部署之前运行 prisma generate
将确保 Prisma 客户端是最新的。
¥This issue can be solved by explicitly generating Prisma Client on every deployment. Running prisma generate
before each deployment will ensure Prisma Client is up-to-date.
你可以将部署配置为以多种不同的方式运行此命令:
¥You can configure the deployment to run this command in multiple different ways:
自定义 postinstall
脚本
¥A custom postinstall
script
这是首选方法,因为它是通用解决方案。
¥This is the preferred method as it is a universal solution.
在项目 package.json
文件的 scripts
部分中,如果还没有名为 postinstall
的脚本,请添加一个脚本并在该脚本中添加 prismagenerate`:
¥Within the scripts
section of your project's package.json
file, if there is not already a script named postinstall
, add one and add prisma generate` in that script:
{
...
"scripts" {
"postinstall": "prisma generate"
}
...
}
应用的 build
脚本位于 package.json
中
¥The application's build
script in package.json
在项目 package.json
文件的 scripts
部分的 build
脚本中,将 prisma generate
添加到现有构建命令之前:
¥Within the scripts
section of your project's package.json
file, within the build
script, prepend prisma generate
to the existing build command:
{
...
"scripts" {
"build": "prisma generate && <actual-build-command>"
}
...
}
Netlify UI 的构建脚本字段
¥Netlify UI's build script field
将 prisma generate
配置为在每个部署上运行的另一种方法是通过 Netlify 的 UI 将命令添加到构建设置。
¥Another way to configure prisma generate
to be run on every deployment is to add the command to the build settings via Netlify's UI.
在项目的仪表板中,转到“站点设置”选项卡并找到“构建和部署”部分。在该部分中,输入持续部署子部分。
¥Within your project's dashboard, go to the Site Settings tab and find the Build & deploy section. In that section, enter the Continuous deployment subsection.
找到标有“构建设置”的部分中的框,然后单击“编辑设置”按钮:
¥Find the box in that section labeled Build settings and click the Edit settings button:
单击该按钮将打开一个包含各个字段的表单。找到 Build command 字段并将 prisma generate
添加到现有脚本中:
¥Clicking that button will open a form with various fields. Find the Build command field and prepend prisma generate
to the existing script: