Post

Express + Prisma + TS 초기세팅 트러블슈팅

Express + Prisma + TS 초기세팅 트러블슈팅

천월고 리팩토링 도중 백엔드 서버 구축 과정, Node.js + Express + TypeScript 환경에서 Prisma(ORM)와 PostgreSQL을 연동하는 초기 세팅 과정에서 발생한 주요 에러들과 해결 방법을 정리해봤다.

1. TypeScript 모듈 시스템 충돌 에러 (CJS vs ESM)

문제 현상

npm run dev로 서버를 실행했을 때, app.ts 파일의 import 구문에서 아래와 같은 에러가 발생하며 서버가 죽음.

TS1295: ECMAScript imports and exports cannot be written in a CommonJS file under 'verbatimModuleSyntax'.

발생 원인

현재 프로젝트는 전통적인 Node.js 모듈 방식인 CommonJS(CJS) 기반으로 설정되어 있다. 하지만 코드에서는 최신 자바스크립트 표준인 ES Modules(ESM) 방식의 import / export 문법을 사용했다.

일반적으로 TypeScript가 이를 알아서 CJS의 require로 변환(컴파일)해주지만, tsconfig.jsonverbatimModuleSyntax 옵션이 true로 켜져 있으면 “개발자가 작성한 import 구문을 내 마음대로 변환하지 않겠다”며 컴파일을 거부하게 된다.

해결 방법

tsconfig.json 파일에서 엄격한 모듈 문법 유지 옵션을 끄거나 삭제한다.

1
2
3
4
5
6
7
8
// tsconfig.json
{
  "compilerOptions": {
    // ... 생략
    "verbatimModuleSyntax": false, //  부분을 false 변경하거나 아예 삭제
    "esModuleInterop": true //  옵션이 true인지 확인 (CJS/ESM 호환성)
  }
}
  • verbatimModuleSyntax: CommonJS 모듈을 ES6 모듈 사양처럼 가져올 수 있게 해주는 옵션. 보통은 false로 설정하여 TypeScript가 CJS와 ESM 간의 호환성을 자동으로 처리하도록 하는 것이 일반적이다.
  • esModuleInterop: CommonJS 모듈을 ES6 스타일로 가져올 수 있게 해주는 옵션. 이 옵션이 true로 설정되어 있으면 import express from 'express'와 같은 구문이 정상적으로 작동한다.

2. Prisma Client 생성 경로 및 타입 인식 에러

문제 현상

컨트롤러 파일에서 Prisma Client를 import하려고 할 때, 아래와 같은 에러가 발생하며 타입이 인식되지 않음.

1
2
TS2305: Module '"@prisma/client"' has no exported member 'PrismaClient'.
Error: An output path is required for the 'prisma-client' generator.

발생 원인

Prisma는 다른 라이브러리처럼 고정된 코드를 다운받는 것이 아니라, 개발자가 작성한 schema.prisma 파일을 분석하여 내 DB 구조에 맞는 TypeScript 코드를 동적으로 생성한다.

하지만, schema.prisma 파일 내에 provider 옵션이 제대로 설정되어 있지 않아서 Prisma Client가 생성되지 않았고, 따라서 @prisma/client 모듈에서 PrismaClient 클래스를 찾을 수 없게 된 것이다.

해결 방법

schema.prisma 파일의 generator 설정에서 provider 이름을 추가하고 코드를 다시 생성한다.

1
2
3
generator client {
  provider = "prisma-client-js"
}
1
npx prisma generate # 터미널에서 코드 다시 생성

이렇게 하면 @prisma/client 모듈이 정상적으로 생성되고, 컨트롤러 파일에서 PrismaClient 클래스를 import할 수 있게 된다.

3. Prisma v7 초기화 에러

코드를 모두 정상적으로 작성하고 실행했으나, 런타임에서 아래와 같은 Prisma 초기화 에러가 발생.

1
PrismaClientInitializationError: 'PrismaClient' needs to be constructed with a non-empty, valid 'PrismaClientOptions'

발생 원인

이것은 내 코드의 문제가 아니라 Prisma 7 버전의 아키텍처 변경 때문이다. Prisma 6 버전 이하에서는 new PrismaClient() 만 호출해도 내부적으로 내장된 DB 엔진(Rust 기반)을 사용해 알아서 연결을 처리했다. 하지만 7 버전부터는 이 내장 엔진이 기본값에서 제외되었고, 직접 DB 종류에 맞는 어댑터를 설치해주고 주입해 주어야만 동작하도록 강제되었다.

해결 방법

최신 7 버전의 어댑터 설정을 새로 적용하기보다는, 안전성이 검증되고 레퍼런스가 많은 Prisma 6 버전으로 다운그레이드하는 것이 효율적이라 생각했다.

1
2
3
4
5
# 1. 기존 7버전을 덮어씌우고 6버전으로 강제 설치
npm install prisma@6 @prisma/client@6

# 2. 6버전 엔진으로 코드 다시 생성
npx prisma generate
This post is licensed under CC BY 4.0 by the author.