class-transformer
class-transformer copied to clipboard
feat: warn users when trying to transform with empty metadata storage
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
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" ] } } }
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.
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, 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
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.
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.
@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. ❤️
@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.
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
@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!