해결 방법으로 래퍼 클래스 없이 Svelte Kit 및 Prisma 통합

5881 단어 prismasvelte
Svelte KitPrisma은 요즘 저에게 꼭 필요한 스택입니다. 프론트엔드의 뛰어난 인체 공학과 서버 측 간의 컨텍스트 전환으로 인한 인지 부하 비용이 적다는 점이 마음에 듭니다.

Svelte Kit, Nuxt 또는 기타 Vite 기반 프레임워크 사용자는 문서에서 제안하는 방식으로 PrismaClient 또는 기타 내보내기를 가져올 수 없습니다1.



그러면 다음을 볼 수 있습니다.


import Prisma, { PrismaClient } from "@prisma/client";
                 ^^^^^^^^^^^^
SyntaxError: Named export 'PrismaClient' not found. The requested module '@prisma/client' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from '@prisma/client';
const { PrismaClient } = pkg;


커뮤니티에 several workarounds known이 있지만 Enum 값을 가져올 수 없거나 SQL 템플릿에 대한 Prisma 개체와 같은 몇 가지 단점이 있습니다.

상황에 따라 Prisma를 사용할 때 사용하는 것은 @prisma/client에 있는 것이 아니라 @prisma/client 내부에서 가져오는 코드 로컬 생성 prisma 생성 명령입니다. Prisma는 스키마를 반영하는 맞춤형 API를 제공해야 하므로 일반 패키지처럼 제공될 수 없습니다.

결과적으로 @prisma/client에는 배포 시 생성된 것으로 추정되는 맞춤형 클라이언트를 가져오기 위한 코드 한두 줄만 포함됩니다. 정말 작은 코드 조각입니다.

const prisma = require('.prisma/client/index')

module.exports = prisma


이것은 애플리케이션 코드와 생성된 코드를 접착하므로 저는 이것을 Prisma의 접착 코드라고 부릅니다.

이것은 CJS 코드가 요구할 때 잘 작동합니다. 마찬가지로, TypeScript나 다른 번들러에 의해 트랜스파일되는 코드는 이러한 도구가 컴파일 타임에 처리되기 때문에 이와 함께 작동할 수 있습니다.

문제는 기본 내보내기 이외의 내보내기를 인식하지 못하는 ES 모듈입니다.

Svelte Kit(구성에 따라 Nuxt 또는 기타 Vite 기반 프레임워크도 알고 있는 한)는 CJS 번들을 내보내는 Next와 달리 ES 모듈을 빌드 아티팩트로 내보내고 이 문제에 직면합니다.

하지만 왜?

ES 모듈이 다른 CJS 모듈에서 명명된 내보내기를 시도하는 경우import Node는 특정 구문에 명시적으로 정의된 내보내기만 인식합니다. 정적 분석으로 실행되기 전에 감지됨2

For better compatibility with existing usage in the JS ecosystem, Node.js in addition attempts to determine the CommonJS named exports of every imported CommonJS module to provide them as separate ES module exports using a static analysis process.

The detection of named exports is based on common syntax patterns but does not always correctly detect named exports.



이 때문에 Prisma의 글루 코드는 노드의 관점에서 기본 내보내기만 효과적으로 다시 내보냅니다. 반면 TS 컴파일러는 어떻게든 명명된 내보내기를 인식했습니다. 이로 인해 dev 서버에서 제대로 작동하는 이상한 상황이 발생하지만 정적import s가 있는 ES 모듈로 프로덕션용으로 번들된 후에는 이와 같은 오류 메시지와 함께 실패합니다.

다행스럽게도 Node는 export.name = value만 감지하지 않습니다. 3과 같이 더 복잡한 구문을 지원하는 것 같습니다.

module.exports = {
  ...require('.prisma/client/index'),
}


a pull request to Prisma로 보냈습니다. 언제 또는 승인될지 확실하지 않지만 당분간 package.json에서 이 후크를 사용할 수 있을 것이라고 가정합니다. 위의 글루 코드 교체(JS 스니펫)가 patches/prisma-fixed-glue.js로 저장되었다고 가정하고 다음을 추가합니다.

  "build": "cp patches/prisma-fixed-glue.js node_modules/@prisma/client/index.js && svelte-kit build",


(저는 기본적으로 no longer supports lifecycle scripts인 pnpm을 사용하는데 활성화 시키거나 npm을 사용하는 한 prebuild를 넣어도 됩니다)



https://www.prisma.io/docs/concepts/components/prisma-client/working-with-prismaclient/instantiate-prisma-client

https://nodejs.org/api/esm.html#commonjs-namespaces

https://github.com/nodejs/cjs-module-lexer/tree/1.2.2

좋은 웹페이지 즐겨찾기