node.js - Korištenje Prisma Sheme u PNPM monorepu s NestJS uzrokovalo ESM probleme
Kreirao sam PNPM monorepo koji ima dvije NestJS aplikacije (apps/api i apps/backend; obje su potpuno iste) i jedan Prisma paket baze podataka (packages/database). Kada pokrenem api pomoću start:dev, dobijem sljedeću pogrešku:
(node:69498) Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/Users/username/Documents/Slug/slug-monorepo/packages/database/src/index.ts:1
export * from "@prisma/client";
^^^^^^
SyntaxError: Unexpected token 'export'
at wrapSafe (node:internal/modules/cjs/loader:1389:18)
at Module._compile (node:internal/modules/cjs/loader:1425:20)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1564:10)
at Module.load (node:internal/modules/cjs/loader:1287:32)
at Function.Module._load (node:internal/modules/cjs/loader:1103:12)
at Module.require (node:internal/modules/cjs/loader:1310:19)
at require (node:internal/modules/helpers:179:18)
at Object.<anonymous> (/Users/username/Documents/Slug/slug-monorepo/apps/api/src/prisma/prisma.service.ts:2:1)
at Module._compile (node:internal/modules/cjs/loader:1480:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1564:10)
Kako mogu koristiti Prismu s NestJS-om u PNPM monorepu?
./pnpm-radni-prostor.yaml
packages:
- 'apps/*'
- 'packages/*'
apps/api/package.json
{
"name": "@slug-monorepo/api",
"version": "0.0.1",
"description": "",
"author": "",
"private": true,
"license": "UNLICENSED",
"scripts": {
"build": "nest build",
"format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
"start": "nest start",
"start:dev": "nest start --watch",
"start:debug": "nest start --debug --watch",
"start:prod": "node dist/main",
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
"test": "jest",
"test:watch": "jest --watch",
"test:cov": "jest --coverage",
"test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
"test:e2e": "jest --config ./test/jest-e2e.json"
},
"dependencies": {
"@nestjs/common": "^10.0.0",
"@nestjs/core": "^10.0.0",
"@nestjs/platform-express": "^10.0.0",
"@slug-monorepo/database": "workspace:*",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1"
},
"devDependencies": {
...
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}
apps/api/tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "ESNext",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": true,
"noImplicitAny": true,
"strictBindCallApply": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true
}
}
apps/api/src/prisma/prisma.service.ts
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@slug/database';
@Injectable()
export class PrismaService extends PrismaClient implements OnModuleInit {
async onModuleInit() {
await this.$connect();
}
}
apps/api/src/slug/dto/createSlug.dto.ts
import {
SlugType
} from '@slug/database';
export class CreateSlugDto {
@IsOptional()
@IsEnum(SlugType)
slug?: SlugType;
}
paketi/baza_podataka/package.json
{
"name": "@slug-monorepo/database",
"version": "1.0.0",
"description": "",
"main": "src/index.ts",
"scripts": {
"build": "tsc"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"@types/node": "^20.14.8",
"prisma": "^5.16.0",
"typescript": "^5.1.3"
},
"dependencies": {
"@prisma/client": "^5.16.0"
}
}
paketi/baza/tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"outDir": "dist"
},
"include": ["./**/*.ts"],
"exclude": ["dist", "node_modules"]
}
paketi/baza-podataka/src/index.ts
export * from "@prisma/client";
Odgovor #1
Nemam pojma o stvarima vezanim uz TypeScript, tako da može varirati, ali gledajući te package.json datoteke, mislim da vidim nekoliko stvari. Prvo, tvoj apps/api/package.json nema ni main ni type. Drugo, u tvojoj packages/database/package.json, mislim da ne možeš imati TypeScript datoteku kao glavni ulaz — mislim da moraš pokazati na transpiliranu verziju koja bi se nalazila u dist.
Ovaj brz članak mi se činio vrlo korisnim. Evo moje najbolje pretpostavke o tome što vam treba:
// File: apps/api/package.json
"license": "UNLICENSED",
+ "type": "module",
+ "main": "dist/apps/api/index.js" // or wherever your transpile is
"scripts": {
// File: packages/database/package.json
"description": "",
- "main": "src/index.ts", // delete this
+ "exports": {
+ "types": "./dist/types.d.ts",
+ "require": "./dist/index.js",
+ "import": "./dist/index.mjs"
+ },
"scripts": {
Nadam se da to pomaže, ili barem usmjerava vas u pravom smjeru.
