You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PNPM Monorepo中NestJS集成Prisma的ESM兼容问题解决

PNPM Monorepo中NestJS与Prisma的正确配置方案

问题场景

我搭建了一个包含两个NestJS应用(apps/api和apps/backend,两者完全相同)与一个Prisma数据库包(packages/database)的PNPM monorepo。运行api的start:dev命令时,出现如下错误:

(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)

问题原因

核心问题在于packages/database的package.json中,main字段直接指向了未编译的TS源码文件src/index.ts。NestJS的start:dev模式依赖ts-node运行,但ts-node在加载monorepo中的本地包时,不会自动编译依赖的TS文件,导致Node.js的CJS加载器直接读取TS文件的export语法,从而抛出语法错误。

解决方案

1. 修正数据库包的package.json配置

更新packages/database/package.json,将入口指向编译后的JS文件,并添加类型声明路径:

{
  "name": "@slug-monorepo/database",
  "version": "1.0.0",
  "description": "",
  "main": "dist/index.js", // 改为编译后的JS文件
  "types": "dist/index.d.ts", // 添加类型声明路径,提供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"
  }
}

2. 确保数据库包先编译再被应用引用

在根目录的package.json中添加编译数据库包的脚本,并在API的启动脚本中前置执行:

// 根目录 package.json
{
  "scripts": {
    "build:database": "pnpm --filter @slug-monorepo/database build"
  }
}

更新apps/api/package.json的启动脚本,确保启动前先编译数据库包:

{
  "scripts": {
    "start:dev": "pnpm build:database && nest start --watch",
    // 其他脚本保持不变
  }
}

如果需要支持热更新时自动重新编译数据库包,可以添加watch脚本到packages/database/package.json:

{
  "scripts": {
    "build": "tsc",
    "watch": "tsc --watch"
  }
}

之后可以在另一个终端运行pnpm --filter @slug-monorepo/database watch,实现数据库包源码变更时自动编译。

3. 修正应用中的导入路径错误

检查应用代码中的导入路径,确保与数据库包的name字段一致。比如apps/api/src/prisma/prisma.service.ts和createSlug.dto.ts中,当前导入的是@slug/database,需要改为@slug-monorepo/database:

// apps/api/src/prisma/prisma.service.ts
import { Injectable, OnModuleInit } from '@nestjs/common';
import { PrismaClient } from '@slug-monorepo/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-monorepo/database'; // 修正路径

export class CreateSlugDto {
  @IsOptional()
  @IsEnum(SlugType)
  slug?: SlugType;
}

4. 验证配置

执行以下步骤验证:

  1. 运行pnpm build:database编译数据库包
  2. 运行pnpm --filter @slug-monorepo/api start:dev启动API服务
  3. 检查是否正常连接数据库,且无语法错误

内容的提问来源于stack exchange,提问作者Dimitri Borgers

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 00:22:25