Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems Encountered with NestJS and pnpm in a Monorepo Setup #13463

Closed
7 tasks done
emochka2007 opened this issue Apr 18, 2024 · 1 comment
Closed
7 tasks done

Problems Encountered with NestJS and pnpm in a Monorepo Setup #13463

emochka2007 opened this issue Apr 18, 2024 · 1 comment
Labels
needs triage This issue has not been looked into

Comments

@emochka2007
Copy link

emochka2007 commented Apr 18, 2024

Is there an existing issue for this?

  • I have searched the existing issues

Current behavior

Problems Encountered with NestJS and pnpm in a Monorepo Setup

Overview

I've been working with NestJS in conjunction with pnpm for managing a monorepo workspace and have encountered numerous issues. Below is the structure of my pnpm-workspace.yaml and a description of the shared folders and microservices within the workspace.

Workspace Configuration

My pnpm-workspace.yaml is configured as follows:

yaml

packages:
  - 'packages/*'
  - 'apps/*'

The packages directory contains a shared folder, and the apps directory is home to my microservices.

Encountered Issues

TypeORM Synchronization Error
While using TypeORM, I frequently get this error upon rebuilding the project:
Interestingly, this occurs when synchronize: true is set in the configuration.
exception EntityMetadataNotFoundError: No metadata for "User" was found.

NestJS Dependency Resolution Error

Another recurring error is related to dependency resolution in NestJS:
Nest can't resolve dependencies of the TypeormModule.
The workaround involves rebuilding the entire project and deleting the root node_modules folder.

Custom Interceptor Dependency Issue

Implementing a custom interceptor results in the following dependency error:
ERROR [ExceptionHandler] Nest can't resolve dependencies of the CustomCacheInterceptor (CACHE_MANAGER, ?). Please make sure that the argument Reflector at index [1] is available in the PostModule context.

Guard Reflection Error

Using custom guards yields a 'not found' error for the reflector:
However, this is fixed by passing a new instance of Reflector to the guard.
ERROR [ExceptionHandler] Nest can't resolve dependencies of the CustomGuard (?). Please make sure that the argument Reflector at index [0] is available in the context.

TypeScript Typing Mismatch

Consistent TypeScript errors are thrown regarding a type mismatch for RmqClient from @nestjs/microservices, indicating an incompatibility between the imported type and the type declared in the shared folder.
Attached screenshot illustrates the TypeScript error in more detail.

Example from a microservice gateway:


constructor(
  @Inject('CHAT_SERVICE') private readonly chatService: ClientRMQ,
) {}
`
Example from the shared folder:
```async handleServiceCall<T extends keyof typeof microserviceEndpoint, D extends { authorId: string }>(
  payload: {
    serviceName: T;
    service: ClientRMQ;
    message: keyof (typeof microserviceEndpoint)[T];
    data: D;
    res?: Response;
    ms?: number;
  }
)

Minimum reproduction code

https://github.com/emochka2007/nestjs-pnpm-issue.git

Steps to reproduce

  1. Create a Monorepo Workspace:

    • Initialize a new workspace with pnpm.
    • Structure your pnpm-workspace.yaml to include both packages/* for shared libraries and apps/* for individual microservices.
  2. Set Up TypeORM:

    • Within one of the microservices, set up TypeORM with the synchronize: true configuration.
    • Attempt to rebuild the project.
  3. Experience the TypeORM Synchronization Error:

    • Observe the EntityMetadataNotFoundError when the project attempts to rebuild.
  4. NestJS Dependency Resolution Error:

    • Try to resolve dependencies of TypeormModule and notice the issue.
    • Attempt to fix this by removing the node_modules folder and rebuilding the project.
  5. Implement a Custom Interceptor:

    • Implement a custom interceptor in any of the services.
    • Add the interceptor to a controller using @UseInterceptors().
  6. Custom Interceptor Dependency Issue:

    • Encounter the dependency resolution error for CACHE_MANAGER and Reflector.
  7. Use Guards with Custom Reflector:

    • Implement a guard and use it with @UseGuards().
    • Pass a new instance of Reflector to the guard.

Expected behavior

  1. TypeORM Synchronization:

    • The synchronize: true configuration in TypeORM should not lead to EntityMetadataNotFoundError during the project rebuild. Instead, it should automatically synchronize the database schema with the entities defined in the project without errors.
  2. NestJS Module Resolution:

    • NestJS should be able to resolve dependencies for modules without having to delete the node_modules directory and rebuild the entire project. The resolution should work correctly with the established structure of the monorepo.
  3. Custom Interceptors:

    • Custom interceptors should be resolved properly without throwing dependency resolution errors. The CACHE_MANAGER and Reflector dependencies should be injectable into the interceptors without issue.
  4. Guards and Reflectors:

    • When using custom guards, the Reflector should be resolved without needing to manually pass a new instance. The framework should automatically provide the required instances wherever they are needed.

Package

  • @nestjs/common
  • @nestjs/core
  • @nestjs/microservices

Other package

@nestjs/typeorm

NestJS version

^10.3.7

Packages versions

    "@nestjs/cache-manager": "^2.2.2",
    "@nestjs/common": "^10.3.7",
    "@nestjs/config": "^3.2.2",
    "@nestjs/core": "^10.3.7",
    "@nestjs/jwt": "^10.2.0",
    "@nestjs/mapped-types": "^2.0.5",
    "@nestjs/microservices": "^10.3.7",
    "@nestjs/passport": "^10.0.3",
    "@nestjs/platform-express": "^10.3.7",
    "@nestjs/platform-socket.io": "^10.3.7",
    "@nestjs/typeorm": "^10.0.2",
    "@nestjs/websockets": "^10.3.7",
    "@packages/shared": "workspace:*",
    "amqp-connection-manager": "^4.1.14",
    "amqplib": "^0.10.4",
    "bcrypt": "^5.1.1",
    "cache-manager": "^5.5.1",
    "class-transformer": "^0.5.1",
    "class-validator": "^0.14.1",
    "express-session": "^1.18.0",
    "gucar-types": "^0.0.8",
    "ioredis": "^5.4.1",
    "joi": "^17.12.3",
    "passport": "^0.6.0",
    "passport-jwt": "^4.0.1",
    "reflect-metadata": "^0.1.14",
    "rxjs": "^7.8.1",
    "socket.io": "^4.7.5"
  },
  "devDependencies": {
    "@nestjs/cli": "^10.3.2",
    "@nestjs/schematics": "^10.1.1",
    "@nestjs/testing": "^10.3.7",
    "@types/express": "^4.17.21",
    "@types/express-session": "^1.18.0",
    "@types/jest": "^29.5.12",
    "@types/node": "^20.12.7",
    "@types/passport-jwt": "^3.0.13",
    "@types/supertest": "^2.0.16",
    "@typescript-eslint/eslint-plugin": "^5.62.0",
    "@typescript-eslint/parser": "^5.62.0",
    "dotenv": "^16.4.5",
    "eslint": "^8.57.0",
    "eslint-config-prettier": "^8.10.0",
    "eslint-plugin-prettier": "^4.2.1",
    "jest": "^29.7.0",
    "prettier": "^2.8.8",
    "source-map-support": "^0.5.21",
    "supertest": "^6.3.4",
    "ts-jest": "^29.1.2",
    "ts-loader": "^9.5.1",
    "ts-node": "^10.9.2",
    "tsconfig-paths": "^4.2.0",
    "typescript": "^5.4.5"
  },

Node.js version

v20.10.0

In which operating systems have you tested?

  • macOS
  • Windows
  • Linux

Other

2024-04-18 19 13 57

@emochka2007 emochka2007 added the needs triage This issue has not been looked into label Apr 18, 2024
@kamilmysliwiec
Copy link
Member

This is a very similar issue to this one #13441 (comment)

The root cause is exactly the same - duplicated @nestjs packages (local copies installed for packages and apps)

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.

@nestjs nestjs locked and limited conversation to collaborators Apr 19, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
needs triage This issue has not been looked into
Projects
None yet
Development

No branches or pull requests

2 participants