Reputation: 278
I've created a PNPM monorepo that has two NestJS apps (apps/api and apps/backend; both are exactly the same) and one Prisma database package (packages/database). When I run the api with start:dev, I get the following error:
(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)
How can I use Prisma with NestJS in a PNPM monorepo?
./pnpm-workspace.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;
}
packages/database/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"
}
}
packages/database/tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "commonjs",
"strict": true,
"esModuleInterop": true,
"outDir": "dist"
},
"include": ["./**/*.ts"],
"exclude": ["dist", "node_modules"]
}
packages/database/src/index.ts
export * from "@prisma/client";
Upvotes: 3
Views: 726
Reputation: 1525
I have no idea about the typescript stuff, so YMMV, but looking at those package.json
files, I think I see a couple of things. First, your apps/api/package.json
has neither a main
nor a type
. Second, in your packages/database/package.json
, I don't think you can have a TypeScript file as the main entry point — I think you have to point it at the transpiled version that would come out in dist
.
I found this quick article very useful. Here's my best guess at what you need:
// 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": {
Hopefully that helps, or at least points you in the right direction.
Upvotes: 1