nest
nest copied to clipboard
Path aliases / relative imports in a monorepo breaks `nest start`
Is there an existing issue for this?
- [X] I have searched the existing issues
Current behavior
When adding an external import to a Nest.js app inside a monorepo, an error occurs when running nest start:dev.
I have setup a repo using pnpm workspaces so that I can share code between different projects. To achieve clean imports I have used path aliases for the shared project, but the same happens when the import uses a relative path. https://github.com/ChazUK/nest-monorepo-import-error/blob/main/nest-project/src/app.controller.ts#L4
Normally running the start or build command creates a dist structure like below:
nest-project/
└─ dist/
├─ src/
│ └─ main.js
└─ src/
├─ main.js
└─ app.controller.ts
But when adding this import it returns a different structure:
nest-project/
└─ dist/
├─ nest-project/
│ └─ src/
│ └─ main.js
├─ shared-project/
│ └─ src/
| └─ index.js
└─ src/
├─ main.js
└─ app.controller.ts
Which then produces this error
Error: Cannot find module '/Users/.../pnpm-monorepo/nest-project/dist/main'
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:1144:15)
at Function.Module._load (node:internal/modules/cjs/loader:985:27)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:135:12)
at node:internal/main/run_main_module:28:49
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "ES2021",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": true,
"noImplicitAny": true,
"strictBindCallApply": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"paths": {
"@shared": ["../shared-project/"]
}
}
}
Minimum reproduction code
https://github.com/ChazUK/nest-monorepo-import-error
Steps to reproduce
pnpm i2pnpm run --filter nest-project start:dev
Expected behavior
Relative imports and path alisases should not break the Nest.js start command
Package
- [ ] I don't know. Or some 3rd-party package
- [X]
@nestjs/common - [X]
@nestjs/core - [ ]
@nestjs/microservices - [ ]
@nestjs/platform-express - [ ]
@nestjs/platform-fastify - [ ]
@nestjs/platform-socket.io - [ ]
@nestjs/platform-ws - [ ]
@nestjs/testing - [ ]
@nestjs/websockets - [ ] Other (see below)
Other package
No response
NestJS version
10.0.0
Packages versions
{
"name": "nest-project",
"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",
"reflect-metadata": "^0.2.0",
"rxjs": "^7.8.1"
},
"devDependencies": {
"@nestjs/cli": "^10.0.0",
"@nestjs/schematics": "^10.0.0",
"@nestjs/testing": "^10.0.0",
"@types/express": "^4.17.17",
"@types/jest": "^29.5.2",
"@types/node": "^20.3.1",
"@types/supertest": "^6.0.0",
"@typescript-eslint/eslint-plugin": "^6.0.0",
"@typescript-eslint/parser": "^6.0.0",
"eslint": "^8.42.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"jest": "^29.5.0",
"prettier": "^3.0.0",
"source-map-support": "^0.5.21",
"supertest": "^6.3.3",
"ts-jest": "^29.1.0",
"ts-loader": "^9.4.3",
"ts-node": "^10.9.1",
"tsconfig-paths": "^4.2.0",
"typescript": "^5.1.3"
},
"jest": {
"moduleFileExtensions": [
"js",
"json",
"ts"
],
"rootDir": "src",
"testRegex": ".*\\.spec\\.ts$",
"transform": {
"^.+\\.(t|j)s$": "ts-jest"
},
"collectCoverageFrom": [
"**/*.(t|j)s"
],
"coverageDirectory": "../coverage",
"testEnvironment": "node"
}
}
Node.js version
20.11.1
In which operating systems have you tested?
- [X] macOS
- [ ] Windows
- [ ] Linux
Other
Install pnpm https://pnpm.io/installation
I'm getting the same issue.
My main seems to have moved from dist/main to dist/src/main recently?
I don't know what I did.
Here's my setup:
- nestjs 10.3.2
- node.js v20.12.1 / npm 10.5.0
- macOS Sonoma 14.4.1 (23E224)
I can't reproduce it in my other macOS:
$ nest new my-project
$ cd my-project
$ npm i
$ npm run build
$ npm start start:prod
main is <projectDir>/dist/main
but in my existing project in my original macOS, main is
<projectDir>/dist/src/main
Here's my tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"declaration": true,
"removeComments": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"target": "ES2021",
"sourceMap": true,
"outDir": "./dist",
"baseUrl": "./",
"incremental": true,
"skipLibCheck": true,
"strictNullChecks": false,
"noImplicitAny": false,
"strictBindCallApply": false,
"forceConsistentCasingInFileNames": false,
"noFallthroughCasesInSwitch": false
}
}
Edit: Problem solved.
The culprit was <projectDir>/jest.config.ts
causing <projectDir>dist/src/main .
i.e. my jest config file was in typescript.
It went back to <projectDir>dist/main
as soon as I migrated back to <projectDir>/jest.config.js
I switched my jest config back to javascript and all is well.
@NhxKR9uxTpAf6 unfortunately that doesn't solve my problem as my dist folder is still being compiled into multiple sub-directories.
Thank you for taking the time to submit your report! From the looks of it, this could be better discussed on our Discord. If you haven't already, please join here and send a new post in the # 🐈 nestjs-help forum. Make sure to include a link to this issue, so you don't need to write it all again. We have a large community of helpful members, who will assist you in getting this to work.