question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Problem with decorators

See original GitHub issue

Current Behavior

I have a nx workspace. This workspace contains of two projects a backend (nest.js) and a web-frontend (next.js) and a shared library. This library handles the http requests. In the library, I store as well the shared interfaces/DTO’s like the following:

import { ApiProperty } from '@nestjs/swagger'

export class AccessTokenResponseDto {
    @ApiProperty({
        example: 'xxxxx.xxxxx.xxxxx',
    })
    public token!: string
}

As you can see I use the decorator @ApiProperty from the @nestjs/swagger package. This line is causing the bug. Using the library on the backend side is fine but importing it on frontend side breaks the website and I receive the following error:

SyntaxError: {PROJECT}/libs/rest-client/src/dto/auth/access-token-response.dto.ts: Support for the experimental syntax 'decorators-legacy' isn't currently enabled (4:5):

After some research I changed my .babelrc.json to babel.config.json. It looks like this change fixed the error above but a new one appeared.

{PROJECT}/node_modules/@nestjs/common/cache/cache.providers.js Module not found: Can't resolve 'cache-manager' in '{PROJECT}/node_modules/@nestjs/common/cache'

I also tried multiple times to reach somebody in slack but I looks like this is a more non-trival issue.

Expected Behavior

I expect that this works without compilation errors.

Steps to Reproduce

  1. Create a simple nx workspace
  2. Add a next.js project and a library.
  3. In this library use the @nestjs/swagger decorators
  4. Import this library in the next.js project

Failure Logs

contents of babel.config.json:

{
    "presets": [
        [
            "@babel/preset-env",
            {
                "useBuiltIns": "usage",
                "corejs": 3
            }
        ],
        "next/babel"],
    "plugins": [
        ["@babel/plugin-proposal-decorators", { "legacy": true }],
        ["@babel/plugin-proposal-class-properties", { "loose": true }]
    ]
}

Environment

>  NX  Report

  @nrwl/angular : Not Found
  @nrwl/cli : 9.4.5
  @nrwl/cypress : 9.4.5
  @nrwl/eslint-plugin-nx : 9.4.5
  @nrwl/express : Not Found
  @nrwl/jest : 9.4.5
  @nrwl/linter : 9.4.5
  @nrwl/nest : 9.4.5
  @nrwl/next : 9.4.5
  @nrwl/node : 9.4.5
  @nrwl/react : 9.4.5
  @nrwl/schematics : Not Found
  @nrwl/tao : 9.4.5
  @nrwl/web : 9.4.5
  @nrwl/workspace : 9.4.5
  typescript : 3.8.3

I maybe should add that I have not that much experience in webpack, babel and bundling so far, but I understand it’s purpose.

Issue Analytics

  • State:closed
  • Created 3 years ago
  • Reactions:6
  • Comments:9 (1 by maintainers)

github_iconTop GitHub Comments

1reaction
METACEOcommented, Aug 9, 2020

@pradeeprajr93 @ericgoe I’ve used the strategy I mentioned above (with more validation examples, too) within this example repo: https://github.com/METACEO/nx-demo-swagger-decorators

1reaction
METACEOcommented, Aug 1, 2020

So, I don’t know how I feel about this, but it is all using mechanisms provided to us. I’ll try my best to break it down.

With the below setup, I can import my-object.ts from a library in both my Nest project and my Angular project. Nest compiles with the Swagger decorator, and my Angular app compiles after having the Swagger decorator replaced with an empty one. Unfortunately you’d have to do this with all of the decorators that are not cross-compatible. This should also go the other way around, using Angular decorators but replacing them with empty decorators for Nest compiles.

Would anyone have any alternative approaches?.. something feels off about this (maybe the scalability?..) but it is again using mechanisms given to us out-of-the-box - no hacks.

libs/api-interfaces/src/lib/my-object.ts

import { ApiProperty } from './decorators-nest';

export class MyObject {
  @ApiProperty()
  objectId: string;
}

libs/api-interfaces/src/lib/decorators-nest.ts

export { ApiProperty } from '@nestjs/swagger';

libs/api-interfaces/src/lib/decorators-angular.ts

import "reflect-metadata";

export function ApiProperty(...args): PropertyDecorator {
  return function () {
  }
}

angular.json

{
  "projects": {
    "my-frontend-angular-app": {
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "configurations": {
            "default": {
              "fileReplacements": [
                // REPLACE THE NEST DECORATOR WITH ANGULAR FRIENDLY
                {
                  "replace": "libs/api-interfaces/src/lib/decorators-nest.ts",
                  "with": "libs/api-interfaces/src/lib/decorators-angular.ts"
                }
              ]
            },
            "production": {
              "fileReplacements": [
                {
                  "replace": "apps/my-frontend-angular-app/src/environments/environment.ts",
                  "with": "apps/my-frontend-angular-app/src/environments/environment.prod.ts"
                },
                // REPLACE THE NEST DECORATOR WITH ANGULAR FRIENDLY
                {
                  "replace": "libs/api-interfaces/src/lib/decorators-nest.ts",
                  "with": "libs/api-interfaces/src/lib/decorators-angular.ts"
                }
              ]
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            // SPECIFY THE DEFAULT DEFINITION
            "browserTarget": "my-frontend-angular-app:build:default"
          },
          "configurations": {
            "production": {
              "browserTarget": "my-frontend-angular-app:build:production"
            }
          }
        }
      }
    }
  }
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Problems with decorators when using class validator #1362
Describe the bug I'm trying to use Nest.js with Class Validator for body validation. I've created an E2E test using ts-jest that passes, ......
Read more >
How to solve REST API routing problem with decorators?
We'll be using Method Decorators to develop routesDecorator. Method Decorators: A Method Decorator is declared just before a method declaration.
Read more >
Solving Logic Problems with Python Decorators - Chelsea Troy
If the decorator pattern is new to you, this video I made for my Python Programming students should help.
Read more >
Error Handling in Python using Decorators - GeeksforGeeks
Error handling using decorators​​ The following example shows how a general error handling code without use of any decorator looks like: Python3.
Read more >
Using the decorator meta-problem — pygmo 2.18.0 ...
The decorator problem generalises this idea by allowing the user to arbitrarily decorate not only the fitness function, but also any other method...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found