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

Turborepo Monorepo中TypeScript编译私有Prisma包问题排查

NestJS引入Monorepo私有database包时的SyntaxError问题分析与解决

问题根因

你的NestJS后端采用commonjs模块规范(见tsconfig/server.json中module: "commonjs"配置),而database私有包的入口代码是ES模块语法的export * from "@prisma/client",且该包未预先编译为CommonJS格式。

NestJS默认使用tsc编译,它会跳过node_modules目录下的文件(即使是Monorepo中软链接的私有包),导致后端运行时直接读取未编译的ES模块代码,Node.js在CommonJS环境下无法识别export语法,因此抛出SyntaxError: Unexpected token 'export'。

为什么前端NextJS可以正常使用?

NextJS的编译链(基于Webpack/SWC)对Monorepo做了针对性优化:

  • 自动识别本地私有包的未编译TS/ES源码,并将其纳入编译流程,转译为浏览器兼容的格式。
  • NextJS的tsconfig配置module: "esnext",本身天然支持ES模块语法,无需额外处理即可直接识别database包的代码。

解决方案

方案1:预先构建database包(推荐)

给database包添加编译流程,输出同时支持CommonJS和ES模块的双格式,适配前后端不同的模块规范:

  1. 添加database包的tsconfig.json:
{
  "$schema": "https://json.schemastore.org/tsconfig",
  "extends": "../tsconfig/base.json",
  "compilerOptions": {
    "target": "es2017",
    "module": "commonjs",
    "declaration": true,
    "outDir": "./dist",
    "strict": true,
    "skipLibCheck": true
  },
  "include": ["index.ts"],
  "exclude": ["node_modules"]
}
  1. 配置database包的package.json:
    指定编译后的入口文件、类型文件,并添加构建脚本:
{
  "name": "@your-org/database",
  "private": true,
  "main": "./dist/index.js",
  "module": "./dist/index.mjs", // 可选,输出ES模块格式适配前端
  "types": "./dist/index.d.ts",
  "scripts": {
    "build": "tsc && tsc --module esnext --outDir dist/esm && mv dist/esm/index.js dist/index.mjs"
  }
}
  1. 用Turborepo管控构建依赖:
    在根目录的turbo.json中配置流水线,确保后端构建前先完成database包的构建:
{
  "pipeline": {
    "build": {
      "dependsOn": ["^build"],
      "outputs": ["dist/**"]
    },
    "dev": {
      "cache": false,
      "dependsOn": ["^dev"]
    }
  }
}

方案2:让NestJS编译时转译database包

修改后端的tsconfig.json,将database包纳入编译范围(不推荐,容易引发路径和编译冲突):

{
  "extends": "tsconfig/server.json",
  "compilerOptions": {
    "outDir": "./dist",
    "baseUrl": "./",
  },
  "include": ["**/*.ts", "../../node_modules/@your-org/database/**/*.ts"],
  "exclude": ["node_modules/**/*", "!../../node_modules/@your-org/database/**/*.ts"]
}

注意:路径需根据你的Monorepo结构调整,且这种方式可能导致编译速度变慢、类型冲突等问题。

方案3:修改database包为CommonJS语法(不推荐)

将database包的入口代码改为CommonJS格式:

module.exports = require("@prisma/client");

此方案会导致前端使用时需要处理CommonJS转ES模块的兼容问题,破坏前端的ES模块生态,因此不推荐。


内容的提问来源于stack exchange,提问作者Robert Tirta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 16:55:25