Prisma 7 で「PrismaClient がない」と言われてビルドが落ちた
Next.js 16 + Prisma 7 のアプリを Vercel に上げたら、ビルドが型チェックで落ちました。
Failed to type check.
./prisma/dev-login.ts:15:10
Type error: Module '"@prisma/client"' has no exported member 'PrismaClient'.@prisma/client は入っています。package.json にも書いてあります。
それでも「PrismaClient なんて無い」と言われます。
手元では再現しません
これが厄介なところでした。ローカルで npm run build すると通ります。
理由は単純で、@prisma/client は生成しないと中身が空だからです。
インストール直後の @prisma/client は器だけで、PrismaClient を持っていません。
prisma generate を走らせて初めて、スキーマから型と実装が書き込まれます。
手元では、過去に一度 prisma generate を実行していました。
その生成物が node_modules に残っていたので通っていただけです。
まっさらな環境(CI、Vercel、node_modules を消した直後)では必ず落ちます。
直し方
package.json の scripts に入れます。
{
"scripts": {
"build": "prisma generate && next build",
"postinstall": "prisma generate"
}
}両方に入れるのは、走るタイミングが違うからです。
postinstall…npm installの直後。依存を入れ直しただけのときに効くbuild… ビルドの直前。キャッシュから復元されて postinstall が走らないときに効く
Vercel はビルドキャッシュを使うため、後者だけ、あるいは前者だけでは すり抜ける状況が起こりえます。片方で十分に見えても、両方入れておくほうが安全です。
確かめ方
「直った」と思ったら、生成物を消してから確認します。これをやらないと、 また手元の残骸に助けられて通ってしまいます。
rm -rf node_modules/@prisma/client node_modules/.prisma
npm install
npx tsc --noEmitnpm install の中で postinstall が走り、型チェックが通れば本物です。
ついでに踏んだもの
Prisma 7 の設定ファイル prisma.config.ts を、dotenv を使って書いていました。
import { config } from "dotenv";
config({ path: ".env.local" });この dotenv を devDependencies に置いていると、
本番インストールで devDependencies を落とす構成では読めなくなります。
prisma.config.ts はビルド時に読まれるので、dependencies へ移すのが安全です。
教訓
手元で通るビルドは、証拠になりません。
node_modules は積み上がった状態で、まっさらな環境と同じではありません。
生成物を作るツール(Prisma、GraphQL Code Generator、protobuf など)を使っているなら、
生成を消してからもう一度動かすのが、いちばん短い確認方法です。
PrismaNext.jsVercelTypeScript