class-transformer icon indicating copy to clipboard operation
class-transformer copied to clipboard

feat: warn users when trying to transform with empty metadata storage

Open NoNameProvided opened this issue 4 years ago • 10 comments

Description

When a user uses a package wich uses it's own class-transformer version the two won't share it's meta-data storage and the outer isntance wont have any meta-data. This will lead to userless transformations as it will give back a simple object.

This is because your dependencies are not flattened and your main code and the external code uses a different version of the library. So your node_modules should look something like this:

node_modules\
  - external_lib\
    - some-code.js
    - node_modules\
      - class-transformer\
  - class-transformer\
your-main-code.js

Because of this structure

  • the extrenal lib will load class-transformer from node_modules\external_lib\node_modules\class-transformer
  • your main code will load it from node_modules/class-transformer

This means the metadata is stored in the extnernal lib's class-validator and you are trying to transform via your main class-validator instance which doesn't know anything about the operators and classes you have created.

To fix this, make sure your node_modules folder contains exactly one class-validator folder.

Proposed solution

We should at least warn the user in these cases but it would be better if we can prevent this scenario. We already have this functionality in class-validator, where a global object store is exposed (I don't like that approach IMO, attaching things to the globa scope is an anti-pattern.)

References #359, #337, #394, #313

NoNameProvided avatar Jul 29 '20 23:07 NoNameProvided

Another workaround mentioned by @marekberger in #313 ref

Try to put a paths mapping into your root tsconfig.json:

{
   "compilerOptions": {
      "baseUrl": "./",
      "paths": {
         "class-transformer": [
            "./node_modules/class-transformer"
         ]
      }
   }
}

NoNameProvided avatar Aug 02 '20 21:08 NoNameProvided

To fix this, make sure your node_modules folder contains exactly one class-validator folder.

Thanks, do you have any suggestions on how to ensure that?

A quick googling on "flatten npm dependency" gave answers like "switch to yarn" which doesn't quite sound like a solution.

arthabus avatar Aug 03 '20 10:08 arthabus

do you have any suggestions on how to ensure that?

You need to make sure that every package you use requires the same version of class-transformer, in that case, NPM will automatically flatten it for you. For example, having class-transformer defined as ^0.3.1 in every package will flatten your dependencies and install always the latest class-transformer on the 0.3.x line for every package.

Your issue comes from propably having class-transformer required as ^0.2.0 and ^0.3.0. Those doesn't have a common version as below version 1.0 the ^ allows only allows patch updates.

NoNameProvided avatar Aug 07 '20 18:08 NoNameProvided

@NoNameProvided, thanks, I've just double checked that and I do have the same version in all projects from the very beginning:

"class-transformer": "^0.2.3"

The problem is still there

arthabus avatar Aug 22 '20 09:08 arthabus

I've also checked that it couldn't be a problem of version difference between the main project and the library. In my case the npm dependency: "class-transformer": "^0.2.3" is declared only in the package.json of the dependency project. The package.json of the main project doesn't include a "class-transformer" dependency entry. It simply inherited the version declared in the dependency project.

sidec15 avatar Apr 05 '21 17:04 sidec15

The problem with the "class-transformer" library is caused by npm link. My situation is the following:

  • I've a project A that has "class-transformer" as dependency
  • I've project B that has project A (and consequently "class-transformer") as dependency

I tried to use npm link to "link" the source code of project A in project B in order to work directly on the source code of both the two projects. Unfortunately npm link simply creates a symlink in node_modules of project B towards the folder (in the file system) of project A. This leads to have the node_modules of project A included in the node_modules of project B. The problem is here because in this way each project imports its specific "class-transformer" dependency. Searching on the web it seems that the nested node_modules folder is a known problem caused by npm link. So I simply decided to abbandon npm link and to use yalc to work locally.

sidec15 avatar Apr 07 '21 17:04 sidec15

@sdecri thank you sir. I spent 6 hours tearing my hair out tonight about why my stuff wont work.... I actually use yarn but had the same issue.... yalc fixed it. ❤️

iDevelopThings avatar Apr 22 '21 22:04 iDevelopThings

@sdecri @iDevelopThings did you both get it to work using yalc link without the package json reference? Because for me, class transformer only uses the correct metadata storage if I use yalc add and add a file reference in my package.json from the consuming project.

driescroons avatar May 05 '21 10:05 driescroons

In my case I didn't touch the package.json file. I did the following:

  • yalc publish in the library project folder
  • yalc link <mylib> in the consuming project

sidec15 avatar May 05 '21 13:05 sidec15

@sdecri your solution works like a charm! I spent a few hours trying to find out a solution until I found your solution. Thank you so much!

OMartinez-NeT avatar Jul 23 '21 20:07 OMartinez-NeT