Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@prisma/nextjs-monorepo-workaround-plugin is not able to handle multiple clients #18069

Open
millsp opened this issue Feb 23, 2023 · 14 comments
Open
Labels
bug/2-confirmed Bug has been reproduced and confirmed. domain/client Issue in the "Client" domain: Prisma Client, Prisma Studio etc. kind/bug A reported bug. tech/typescript Issue for tech TypeScript. topic: bundler topic: monorepo topic: Next.js topic: @prisma/nextjs-monorepo-workaround-plugin topic: webpack

Comments

@millsp
Copy link
Member

millsp commented Feb 23, 2023

Bug description

@prisma/nextjs-monorepo-workaround-plugin is not able to handle multiple generated clients in a monorepo setup, which are then most commonly bundled together via a Next.js app. The current logic poorly attempts to manage multiple schemas, and thus ends up updating the paths to only one schema across all the bundled clients. This obviously does not work and leads to various errors depending on how much the two schemas differ.

#12853 (comment)
#12921 (comment)
#17687 (comment)
#17687 (comment)

How to reproduce

https://github.com/trentonsnyder/nextjs-prisma-repro (thanks @trentonsnyder)

Expected behavior

Multiple schemas can be handled without any issue when multiple clients are bundled.

Prisma information

n/a

Environment & setup

  • OS: n/a
  • Database: n/a
  • Node.js version: n/a

Prisma Version

4.11.0-dev
@alvis
Copy link

alvis commented Mar 27, 2023

For a monorepo setup with pnpm, I figure out that if you set shared-workspace-lockfile=false in .npmrc file. You'd end up having separate node_modules per each package and hence avoiding prisma generate overwrite the client for every single project in the monorepo.

@janpio
Copy link
Member

janpio commented Apr 20, 2023

@edmbn is also affected by this: #18227 (comment)

@edmbn
Copy link

edmbn commented Apr 21, 2023

I can confirm that this workaround just worked for me: #17687 (comment). Importing from node_modules and not using of the plugin works.

@jakeleventhal
Copy link

Came across this problem myself

@jakeleventhal
Copy link

jakeleventhal commented May 5, 2023

@edmbn I had trouble getting that solution (via #17687 (comment) and https://github.com/adrianbienias/nextjs-prisma-monorepo-issue) working for myself, but it's because my repo has the package nested one level deeper. Getting the node modules path to the root node_modules folder and removing the @prisma/nextjs-monorepo-workaround-plugin works for me

@janpio given the above, i feel like this package should be deprecated and the warning message that prisma gives about the missing schema file should link to some blog post explaining this.

@janpio
Copy link
Member

janpio commented May 5, 2023

Thanks for the highlight of the reproduction and that workaround, we will take a look at specifically this one to understand if there is something our @prisma/nextjs-monorepo-workaround-plugin could to for these cases. This is a pretty tricky situation :/

@filipechagas
Copy link

Hello everyone 👋
I tried #17687 (comment) as well but now I'm getting the other error PrismaClientInitializationError: Your schema.prisma could not be found, and we detected that you are using Next.js..

Has anybody else faced the same issue?

@stephenasuncionDEV
Copy link

I have a turborepo, and have multiple prisma clients. Here is what worked out for me:

output = "../../../node_modules/@prisma/client/dataproxy"
output = "../../../node_modules/@prisma/client/mongodb"
import { PrismaClient } from "@prisma/client/dataproxy";
import { PrismaClient } from "@prisma/client/mongodb";

@jakeleventhal
Copy link

@stephenasuncionDEV the problem with this approach is that you then have a binary for each application in @prisma/client/

For deployments, you either eat the cost of unused binary bloat, or you have to do hacky sed magic

@filipechagas
Copy link

Hey @stephenasuncionDEV and did you have to use nextjs-monorepo-workaround-plugin with it?

@stephenasuncionDEV
Copy link

Hey @stephenasuncionDEV and did you have to use nextjs-monorepo-workaround-plugin with it?

Hi, I did not use any plugins. I just literally changed the output path.

@jakeleventhal
Copy link

jakeleventhal commented Aug 2, 2023

@filipechagas I am doing the same currently, and have this custom GH action clear up the package

name: Clean Prisma Package
description: Cleans out Prisma files from other applications that are not needed in a deployed application.

inputs:
  working-directory:
    description: The working directory for the application.
    required: true

runs:
  using: composite
  steps:
    - name: Clean Prisma Package
      shell: bash
      working-directory: ${{ inputs.working-directory }}
      run: |
        # Delete output from other applications
        set -x
        pwd
        ls ../../../node_modules/@prisma/client
        app=$(echo "${{ inputs.working-directory }}" | cut -d'/' -f2)
        for dir in ppc artelo ecominate; do
          if [ "$dir" != "$app" ]; then
            rm -rf "../../../node_modules/@prisma/client/$dir";
          fi
        done

My different database packages in my repo are ppc, artelo, and ecominate

@kyle-turn2
Copy link

@stephenasuncionDEV I am doing this exact thing but am getting:

../../packages/db-postgres/index.ts:1:0
Module not found: Can't resolve '@prisma/client/postgres'
> 1 | import { PrismaClient } from "@prisma/client/postgres";
  2 | 
  3 | const prismaClientSingleton = () => {
  4 |   return new PrismaClient({

https://nextjs.org/docs/messages/module-not-found

Would you mind elaborating on how you have your turborepo setup? Where do you have the prisma generate wired up?

I have two packages setup with an index.ts that look like this:

import { PrismaClient } from "@prisma/client/postgres"; 
//the other one is importing from "@prisma/client/sqlserver"

const prismaClientSingleton = () => {
  return new PrismaClient();
};

type PrismaClientSingleton = ReturnType<typeof prismaClientSingleton>;

const globalForPrisma = globalThis as unknown as {
  prisma: PrismaClientSingleton | undefined;
};

const prisma = globalForPrisma.prisma ?? prismaClientSingleton();

export default prisma;

if (process.env.NODE_ENV !== "production") {
  globalForPrisma.prisma = prisma;
}

@Sardonyx001
Copy link

stephenasuncionDEV

Can confirm this fix worked for me. Apparently if you put your other clients under /client instead of beside it it works

This didn't work for me

# main db
output = "../../../node_modules/@prisma/client"
# other dbs
output = "../../../node_modules/@prisma/dataproxy-client"
output = "../../../node_modules/@prisma/mongodb-client"

This worked

# main db
output = "../../../node_modules/@prisma/client"
# other dbs
output = "../../../node_modules/@prisma/client/dataproxy"
output = "../../../node_modules/@prisma/client/mongodb"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug/2-confirmed Bug has been reproduced and confirmed. domain/client Issue in the "Client" domain: Prisma Client, Prisma Studio etc. kind/bug A reported bug. tech/typescript Issue for tech TypeScript. topic: bundler topic: monorepo topic: Next.js topic: @prisma/nextjs-monorepo-workaround-plugin topic: webpack
Projects
None yet
Development

No branches or pull requests

9 participants