Yarn Berry 환경과 PnP 기능에서 Prisma 사용

SeokHun·2023년 2월 24일
2
post-thumbnail

Prisma 사용 방법이 아닌 오류 해결에 관한 글입니다.

Yarn Berry 환경 사용 이유

현재 블로그를 개발하고 있는데 나의 프로젝트의 상황은 현재 이러하다

  1. 하나의 Repository에 여러 프로젝트를 관리하고 있는 상황이다
    (현재는 Front-end와 Back-end를, 이후 직접 서버 인스턴스를 구축할 때 확장 가능성 염두)
  2. 하나의 블로그 서비스를 제공하는 것이 목적이기 때문에 Type 지정 시 공통 Type이 있을 수 있다

따라서 Yarn Berry 환경으로 구축해 workspace 기능을 손쉽게 사용하고 PnP 기능과 함께 Zero Install 설정으로 배포 속도를 높여보고자 했다.

Prisma 사용

Back-end 개발 과정에서 데이터베이스 구축을 어떻게 진행할 것인지 고민을 많이 했었다.

  • postgreSQLmysql
  • graphQLRestAPI
  • 어떤 ORM을 사용할까...

이러니 저러니 해도 결국 내가 개발하는 블로그였기 때문에 선택의 자유가 높았다.
새로 공부할 수 있으면서도 러닝 커브가 크지 않았으면 했기 때문에 이미 사용해본 바 있는 mysql과 함께 새로운 ORM인 prisma를 사용해보고자 했다.

문제 발생

그렇게 개발을 진행하던 도중 문제가 발생했다.

  1. prisma 스키마 파일 생성
  2. prisma generate 명령어를 통해 @prisma/client 라이브러리에 스키마 관련 파일을 생성
  3. 해당 변경된 파일들을 통해 PrismaClient 코드에 접근 가능

위와 같은 로직으로 동작되어야 하는 코드에서 결국 다음과 같은 오류가 발생한다.

'"@prisma/client"' 모듈에 내보낸 멤버 'PrismaClient'이(가) 없습니다.
'"@prisma/client"' has no exported member 'PrismaClient'.

혹은 오류가 발생하지 않더라도 Type추론이 되지 않을 가능성이 높다.

현재 나의 프로젝트는 Yarn Berry 환경에서는 node_modules 폴더가 아닌 PnP로 되어있는 라이브러리 파일을 참조하기 때문에 기본 prisma 설정으로는 나의 스키마에 대한 코드를 덮어씌울 수 없기 때문이다.

접근

prisma 폴더 내에서 다음과 같이 결과물 코드를 어디에 놓을 것인지 설정할 수 있다.

generator client {
  provider      = "prisma-client-js"
  output = "../../... 경로"
}

결국 핵심은 prisma generate를 통해 생성된 코드를 어떻게 사용할 것인가 이다.

해결

  1. 먼저 @yarnpkg/pnpify 를 통해 prisma generate를 실행할 수 있도록 한다.
    그렇지 않으면 package-lock.json 파일과 node_modules 파일이 생성된다.

    yarn add @yarnpkg/pnpify
  2. 그 후 다음과 같이 prisma 파일 코드를 변경한다.

    generator client {
      provider = "prisma-client-js"
      output = "./"
    }
    
    datasource db {
      provider = "mysql"
      url      = env("DATABASE_URL")
    }
    
    ... DB 내용
  3. @yarnpkg/pnpify 라이브러리를 통해 prisma generate를 실행해준다.

    yarn pnpify prisma generate
  4. 해당 파일을 사용한다.
    나는 라이브러리를 잘 사용하기 위해 tsconfig에서 절대 경로를 설정해 사용했다.

     // tsconfig.json
     {
       "compilerOptions": {
         "baseUrl": "./",
         "paths": {
           "@prisma": ["./prisma/index"],
           //...
         }
       }
    }
    // 동작!
    import { PrismaClient } from "@prisma";
     const prisma = new PrismaClient();
    
    // ...
  5. 해당 파일을 라이브러리처럼 사용하기 때문에 .gitignore에 추가해주었다.

    # prisma build files 
    prisma/*
    !prisma/schema.prisma
  6. 명령어를 사용하기 쉽게 package.json에서 설정도 해서 완료!

    // ...  
    "scripts": {
        "dev": "nodemon --exec ts-node -r tsconfig-paths/register ./src/app.ts",
        "prebuild": "yarn prisma:generate",
        "build": "yarn prebuild && yarn tsc",
        "start": "yarn build && node ./build/app.js --node-args='-r ./tsconfig-paths-bootstrap.js'",
        "prisma:generate": "yarn pnpify prisma generate"
      },
    // ...

다른 방법

검색중 nwlee - Yarn PnP 프로젝트에 Prisma ORM 붙이는 방법 해당 블로그의 글도 있었다.

  1. yarn 프로젝트에 typescript 적용하기

    # 이 작업이 필요하다
    yarn plugin import typescript
    # vscode 에서 typescript를 인식하기 위한 명령어
    yarn dlx @yarnpkg/sdks vscode
  2. .yarnrc.yml 파일 수정하기

    nodeLinker: node-modules
    
    plugins:
      - path: .yarn/plugins/@yarnpkg/plugin-typescript.cjs
        spec: '@yarnpkg/plugin-typescript'
    
    yarnPath: .yarn/releases/yarn-3.2.1.cjs
  3. PnP 방식으로 설치되지 않도록 설정

    yarn unplug prisma @prisma/client

여기서는 라이브러리들을 node_modules폴더를 사용하고 참조하게 함으로서 이를 가능하게 하는 방법을 확인하기는 했는데, 라이브러리 파일을 중복으로 가지고 있는 것 같아 패스했다.

참고

https://github.com/prisma/prisma/issues/8765

2개의 댓글

comment-user-thumbnail
2023년 10월 23일

A 라이브러리에서 @prisma/client 라이브러리를 참조할 경우 .prisma 의존성 오류 발생

해결 방법

[.yarnrc.yaml]
packageExtensions:
"@prisma/client@":
peerDependencies:
.prisma: "
"
peerDependenciesMeta:
.prisma:
optional: true

만약 A 라이브러리가 @prisma/client 를 peerDependency 로 설정하지않았다면,
yarnrcl.yaml 에 peerDependency 추가해야 함

[package.json]
{
// ...
"dependencies": {
// prisma generated 경로 (client/index.js 를 참조하기에, 실제 schema 의 output 은 ./prisma/client/ 이어야 함)
".prisma": "link:./prisma",
// ...
}
}

답글 달기
comment-user-thumbnail
2024년 5월 28일

혹시 npx prisma db seed 부분에서는 오류 없으셨나요?

답글 달기