NX Monorepo编译报错:rootDir需包含所有源文件
问题场景
在NX Monorepo中搭建了NestJS+React项目,包含多个用于共享类型和DTO的共享库(如@ems/validation)。为实现TypeORM迁移,需使用TSC而非Webpack编译NestJS项目,但编译时出现以下错误:
apps/backend/src/app/users/dto/create-user.dto.ts:1:41 - error TS6059: File '/ems/shared/validation/src/index.ts' is not under 'rootDir' '/ems/apps/backend'. 'rootDir' is expected to contain all source files.
Imported via '@ems/validation' from file '/ems/apps/backend/src/app/users/dto/create-user.dto.ts'
Imported via '@ems/validation' from file '/ems/apps/backend/src/app/users/users.service.ts'
Imported via '@ems/validation' from file '/ems/apps/backend/src/app/auth/auth.service.ts'
Imported via '@ems/validation' from file '/ems/apps/backend/src/app/auth/auth.controller.ts'
根目录tsconfig.base.json配置如下:
{ "compileOnSave": false, "compilerOptions": { "rootDir": ".", "sourceMap": true, "declaration": false, "moduleResolution": "node", "emitDecoratorMetadata": true, "experimentalDecorators": true, "importHelpers": true, "target": "es2015", "module": "esnext", "lib": ["es2020", "dom"], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".", "paths": { "@ems/services": ["shared/services/src/index.ts"], "@ems/types": ["shared/types/src/index.ts"], "@ems/ui": ["shared/ui/src/index.ts"], "@ems/validation": ["shared/validation/src/index.ts"] } }, "exclude": ["node_modules", "tmp"] }
已尝试重置NX缓存、修改tsconfig(包括移除rootDir: "."),但问题未解决。
解决方案
1. 为NestJS后端单独配置tsconfig
在apps/backend目录下创建/修改tsconfig.json,覆盖rootDir并显式包含共享库:
{ "extends": "../../tsconfig.base.json", "compilerOptions": { "rootDir": "../../", // 指向Monorepo根目录,覆盖默认的backend目录 "outDir": "../../dist/apps/backend", "module": "commonjs", // TypeORM迁移需要commonjs模块格式 "target": "es2017" }, "include": ["src/**/*", "../../shared/**/*"], // 同时包含后端源码和共享库文件 "exclude": ["node_modules", "tmp"] }
2. 调整TypeORM迁移脚本
在项目根目录的package.json中,指定使用后端的tsconfig编译:
{ "scripts": { "typeorm:migrate": "ts-node -r tsconfig-paths/register --project apps/backend/tsconfig.json node_modules/typeorm/cli.js migration:run" } }
3. 预构建共享库(可选)
如果共享库需要编译后再被后端引用,先执行NX构建命令:
nx build validation
然后修改后端tsconfig的paths指向编译后的文件:
"paths": { "@ems/validation": ["dist/shared/validation/src/index.js"] }
4. 检查NX workspace配置
确认nx.json中后端项目的build target配置正确,确保编译时依赖共享库:
{ "projects": { "backend": { "targets": { "build": { "executor": "@nrwl/nest:build", "options": { "outputPath": "dist/apps/backend", "tsConfig": "apps/backend/tsconfig.json", "assets": ["apps/backend/src/assets"], "externalDependencies": ["@ems/validation"] } } } } } }
原因分析
TS6059错误的核心是TSC要求所有被导入的源码文件必须在rootDir指定的目录范围内。直接编译backend时,默认rootDir被限定为apps/backend,导致外部共享库文件不在范围内。将rootDir指向Monorepo根目录,并显式包含共享库文件,即可解决该问题。
内容的提问来源于stack exchange,提问作者szelephezag

