prisma: `ENOENT` with custom output and ESM module in NPM monorepo (including Nextjs): `no such file or directory, open /.../schema.prisma...`
Bug description
I’ve been seeing a slew of issues involving using Prisma-based local packages in an NPM monorepo with Nextjs, and I’ve encountered a case I could not solve using the existing solutions.
As a recap of the other issues, it seems when using a Prisma-based package (i.e. a package that ships with its own prisma.schema
) in Nextjs, the resulting webpack bundles will look for schema.prisma
relative to the directory of the bundle rather than the directory of the package dist
. This results in errors like this:
Error: ENOENT: no such file or directory, open '/.../.next/cache/webpack/client-development/schema.prisma'
Now there have been some proposed solutions thus far, but the big difference is my package is an ESM package whereas the ones in the previous issues have been CJS packages. For example, one of the workarounds proposed here says to modify the Next config to use webpack externals and outputFileTracingRoot
like so:
module.exports = {
output: 'standalone',
experimental: {
outputFileTracingRoot: path.join(__dirname, '../../'),
},
webpack: (config, { buildId, dev, isServer, defaultLoaders, webpack }) => {
config.externals = [...config.externals, '<PACKAGE>']
return config
},
}
However, if <PACKAGE>
is an ESM module, this means webpack never transpiles it to CJS, resulting in a Error: require() of ES Module
error when you try using the package in a Nextjs app. Hence, this fix does not work for ESM-based packages.
How to reproduce
I have created a repro repo here: https://github.com/slimshreydy/prisma-monorepo-esm-output-bug. See the README for instructions on local setup.
Expected behavior
Importing a package that uses prisma in Nextjs should look for the schema.prisma
file in the package’s dist directory rather than the .next/
folder.
Prisma information
generator client {
provider = "prisma-client-js"
output = "./client"
}
datasource db {
provider = "mysql"
url = env("DATABASE_URL")
}
model User {
id Int @id @default(autoincrement())
email String @unique
createdAt DateTime @default(now())
}
import { NextApiRequest, NextApiResponse } from "next";
import { prisma } from "@prisma-monorepo-esm-output-bug/package/dist";
export default async (req: NextApiRequest, res: NextApiResponse) =>
res.json(await prisma.user.findMany());
Environment & setup
- OS: macOS 10.15
- Database: PlanetScale
- Node.js version: v18.12.1
Prisma Version
prisma : 4.9.0
@prisma/client : 4.9.0
Current platform : darwin
Query Engine (Node-API) : libquery-engine ceb5c99003b99c9ee2c1d2e618e359c14aef2ea5 (at ../node_modules/@prisma/engines/libquery_engine-darwin.dylib.node)
Migration Engine : migration-engine-cli ceb5c99003b99c9ee2c1d2e618e359c14aef2ea5 (at ../node_modules/@prisma/engines/migration-engine-darwin)
Introspection Engine : introspection-core ceb5c99003b99c9ee2c1d2e618e359c14aef2ea5 (at ../node_modules/@prisma/engines/introspection-engine-darwin)
Format Binary : prisma-fmt ceb5c99003b99c9ee2c1d2e618e359c14aef2ea5 (at ../node_modules/@prisma/engines/prisma-fmt-darwin)
Format Wasm : @prisma/prisma-fmt-wasm 4.9.0-42.ceb5c99003b99c9ee2c1d2e618e359c14aef2ea5
Default Engines Hash : ceb5c99003b99c9ee2c1d2e618e359c14aef2ea5
Studio : 0.479.0
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 3
- Comments: 17 (6 by maintainers)
Commits related to this issue
- https://github.com/prisma/prisma/issues/17687 applied changes. Seems to work, but NextJS fails to send data — committed to Rafcin/oxygen by Rafcin a year ago
For those using multiple Prisma Clients, we are going to schedule follow-up work via https://github.com/prisma/prisma/issues/18069. Please upvote it if you need multi-client support, and don’t hesitate to share more information there.
@millsp, I’ve tried, and it doesn’t work. Using
experimental-prisma-webpack-plugin
and changes in Next.js config from the workaround you linked, I’m getting the error:Could not find mapping for model <model_name>
I have the same problem. Here’s the repo that reproduces the issue: https://github.com/adrianbienias/nextjs-prisma-monorepo-issue
I’ve added a workaround branch to the repo and explained it in the README.
Steps that worked for me as a temporary solution are quite simple:
output
inschema.prisma
to shared monoreponode_modules
@prisma/client/<package_name>
Hey @slimshreydy thanks for the thorough issue description. We really appreciate the effort! I just tried your reproduction and I have a few remarks. Right now, your reproduction does not fail for me, as it seems you already enabled the workaround and found how to circumvent your ts/esm issue. Could you please provide a branch with the repro that matches your description?
I have seen this problem with TypeScript a few days ago so I am working on a better workaround. We are building a webpack plugin that will fix that for you. In short, this plugin ensures that the necessary files are correctly copied for you but does not conflict with your other settings. You can try it now via https://www.npmjs.com/package/experimental-prisma-webpack-plugin
@Rafcin Packages in my repo aren’t separated in order to handle prisma. They are separated to represent a random package that uses its own
schema.prisma
.T3 app should work well the same way.
In
<monorepo-root>/t3-app/prisma/schema.prisma
set for the client generatoroutput = "../../node_modules/@prisma/client/t3-app"
and in
db.ts
setimport { PrismaClient } from "@prisma/client/t3-app"
Also, remember to include
t3-app
in monorepo rootpackage.json
inworkspaces
, so it will use shared rootnode_modules
.Hi @millsp! Were you trying the app locally (using
npm run dev -w web
to start the server in dev mode), or did you deploy it to Vercel? Onmain
, I was encountering issues with the former but the latter worked fine for me. Using the webpack externals workaround locally causes a “require of ESM module” error (presumably since webpack never ends up transpiling the module).Regardless, I was able to add
experimental-prisma-webpack-plugin
to my Nextjs app and I am happy to report it works! Both the local and hosted versions of my nextjs work fine now. No more ENOENT errors! Thanks for your quick work here.@janpio Tagging you since it seems you’ve been addressing most of these issues!