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

TypeScript Monorepo构建时出现MODULE_NOT_FOUND错误求助

问题

开发时用nodemon + ts-node运行TypeScript Monorepo(包含API和通用代码包)完全正常,但构建后启动API时出现模块找不到错误:

Error: Cannot find module '@cas/common/src/Errors'
Require stack:
- mono-test\@app\api\build\src\config.js
- mono-test\@app\api\build\src\index.js
    at Module._resolveFilename (node:internal/modules/cjs/loader:1077:15)
    at Module._load (node:internal/modules/cjs/loader:922:27)
    at Module.require (node:internal/modules/cjs/loader:1143:19)
    at require (node:internal/modules/cjs/helpers:119:18)
    at Object.<anonymous> (mono-test\@app\api\build\src\config.js:7:34)
    at Module._compile (node:internal/modules/cjs/loader:1256:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1310:10)
    at Module.load (node:internal/modules/cjs/loader:1119:32)
    at Module._load (node:internal/modules/cjs/loader:960:12)
    at Module.require (node:internal/modules/cjs/loader:1143:19) {
  code: 'MODULE_NOT_FOUND',
  requireStack: [
    'mono-test\\@app\\api\\build\\src\\config.js',
    'mono-test\\@app\\api\\build\\src\\index.js'
  ]
}

文件夹结构

@app
  - api
    - build
    - src
      - index.ts
      - ...
    - package.json
    - tsconfig.json
packages
  - common
    - build
    - src
      - Errors.ts // 无index.ts文件
    - .gitignore
    - package.json
    - tsconfig.json

根目录tsconfig.json

{
  "compilerOptions": {
    "composite": true,
    "strict": true,
    "module": "commonjs",
    "target": "es6",
    "moduleResolution": "Node",
    "esModuleInterop": true
  },
  "references": [
    { "path": "./@app/api" },
    { "path": "./packages/common" }
  ]
}

API包配置

package.json

{
  "name": "@user/api",
  "version": "1.0.0",
  "main": "build/index.js",
  "types": "build/index.d.ts",
  "scripts": {
    "start": "node build/src/index.js",
    "build": "tsc",
    "dev": "nodemon --exec ts-node src/index.ts"
  },
  "dependencies": {
    "@cas/common": "^1.0.0",
    "body-parser": "^1.20.2",
    "express": "^4.18.2"
  },
  "devDependencies": {
    "@types/express": "^4.17.21",
    "nodemon": "^3.0.2"
  }
}

tsconfig.json

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "./build",
    "baseUrl": "./src",
    "composite": true,
    "strict": true,
    "module": "commonjs",
    "target": "es6",
    "moduleResolution": "node",
    "esModuleInterop": true
  },
  "references": [
    { "path": "../../packages/common" }
  ]
}

Common包配置

package.json

{
  "name": "@cas/common",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "scripts": {
    "build": "tsc"
  },
  "dependencies": {},
  "devDependencies": {}
}

tsconfig.json

{
  "extends": "../../tsconfig.json",
  "compilerOptions": {
    "outDir": "./build",
    "composite": true,
    "baseUrl": "./src"
  }
}

已确认先构建common包再构建api包,且api包已执行npm install,但错误仍存在。


解决方法

1. 修复Common包的package.json配置

Common包的main字段指向不存在的index.js,且未配置构建后文件的导出规则,导致Node无法找到正确的模块路径。

修改packages/common/package.json:

  • 方式一(仅导出Errors模块):
    "main": "build/src/Errors.js",
    "types": "build/src/Errors.d.ts"
    
  • 方式二(支持多模块导出,更灵活):
    "exports": {
      "./src/Errors": "./build/src/Errors.js",
      "./src/Errors.d.ts": "./build/src/Errors.d.ts"
    },
    "typesVersions": {
      "*": {
        "src/Errors": ["build/src/Errors.d.ts"]
      }
    }
    

2. 配置Monorepo Workspaces(关键)

根目录未配置workspaces,导致npm install时可能安装了远程的@cas/common包,而非本地包。在根目录package.json中添加:

"workspaces": [
  "@app/*",
  "packages/*"
]

然后在根目录执行npm install,确保本地包被正确链接到api的node_modules中。

3. 调整API中的导入路径(可选,更规范)

如果使用方式二的exports配置,API中的导入语句可以保持import { ... } from '@cas/common/src/Errors';如果用方式一,建议改为直接导入包:

import { ... } from '@cas/common'

同时在Common包的src目录添加index.ts,导出Errors模块:

export * from './Errors';

并同步修改Common包的package.json:

"main": "build/index.js",
"types": "build/index.d.ts"

4. 清理旧构建文件并重新构建

删除旧的build目录,按顺序重新构建:

# 清理构建文件
rm -rf packages/common/build @app/api/build

# 构建Common包
cd packages/common && npm run build

# 构建API包
cd ../../@app/api && npm run build

5. 可选:添加TypeScript路径映射(优化开发体验)

在API的tsconfig.json中添加paths字段,确保开发时路径解析正确:

"compilerOptions": {
  // ...其他配置
  "paths": {
    "@cas/common/*": ["../../packages/common/src/*"]
  }
}

注意:构建后Node不识别paths,所以必须配合Common包的package.json导出配置使用,或使用tsconfig-paths工具在启动时解析路径(在API的start脚本中添加:tsconfig-paths/register):

"scripts": {
  "start": "node -r tsconfig-paths/register build/src/index.js"
}

内容的提问来源于stack exchange,提问作者jp j

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 09:00:55