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 は、依存関係がインストールされる際に Prisma Client を生成するために `postinstall` フックを使用します。Vercel はキャッシュされたモジュールを使用するため、この `postinstall` フックは初回デプロイ後の後続のデプロイでは実行されません。その結果、Prisma Client がデータベーススキーマと同期しなくなります。
このエラーメッセージは、この状況が発生するのを防ぎ、根本的な問題を修正する方法を学ぶためにここへ誘導します。
Prisma Client バージョン 4.13.0 未満
Prisma Client バージョン 4.13.0 未満では、以下のようなエラーメッセージに遭遇する場合があります。
// 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"
}
...
}
アプリケーションの `package.json` 内の `build` スクリプト
プロジェクトの `package.json` ファイルの `scripts` セクション内にある `build` スクリプトで、デフォルトの `vercel build` コマンドの前に `prisma generate` を追加します。
{
...
"scripts" {
"build": "prisma generate && <actual-build-command>"
}
...
}
Vercel UI のビルドスクリプトフィールド
`prisma generate` をデプロイごとに実行するように設定するもう1つの方法は、Vercel の UI を介してビルド設定にコマンドを追加することです。
プロジェクトのダッシュボード内で、設定タブに移動し、一般セクションを見つけます。そのセクションには、ビルドと開発の設定というラベルのボックスがあり、ビルドコマンドという入力フィールドが含まれています。
そのフィールド内で、既存のスクリプトの前に `prisma generate` を追加します。