Skip to content

Declarations are unexpectedly used from node_modules in parent directory #30124

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

Closed
leemhenson opened this issue Feb 27, 2019 · 19 comments
Closed
Assignees
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug

Comments

@leemhenson
Copy link

TypeScript Version: 3.4.0-dev.20190227
Search Terms: nested node_modules module resolution

I have a project nested inside another project. Both package.jsons import the same library, but they are two different versions of the library.

Issue
In the files inside the inner project, I am able to import something that is only exported by the version of the library used by the outer project. When I open just the inner project in VSCode, I see two entries in the import intellisense for each export from the shared library, one from each version. It appears that Typescript is recursing up the directory tree, looking for node_modules and merging their declarations even through the library is already installed in the local node_modules.

Code

Here's the import that should fail. I should only be able to import from "fp-ts/lib/HKT" here:

https://github.com/leemhenson/fp-ts-oom-repro/blob/master/subproject/user.ts#L2

Here's the inner project's import of the library:

https://github.com/leemhenson/fp-ts-oom-repro/blob/master/subproject/package.json#L7

Here's the outer project's import of the library:

https://github.com/leemhenson/fp-ts-oom-repro/blob/master/package.json#L8

I've tried settings types: [] and typeRoots, exclude: ["../node_modules"] etc.

Related
#11994
#11363
#11257

@j-oliveras
Copy link
Contributor

Did you tried using Path mapping? Be aware that will not rewrite your imports.

@leemhenson
Copy link
Author

    "paths": {
      "fp-ts/lib/*": ["./node_modules/fp-ts/lib/*"]
    },

and variants have no effect.

@RyanCavanaugh RyanCavanaugh added the Needs Investigation This issue needs a team member to investigate its status. label Feb 27, 2019
@burtonator
Copy link

I have the same problem. what I think is happening is that:

node_modules/typescript/lib/typesMap.json

has an entry for 'md5' (and other things) and it's using the parent mode_modules for resolving it.

I then get a ton of other associated errors due to module differences.

I tried changing typeRoots, exclude, and paths and none of them work. The documentation is incorrect that parent directories will not be used.

The only work around I've found is to move the parent node_modules out of the way.

The root cause is that typescript tries to pull it's own things in which I didn't specify and there's no way to disable this or tell it to not load from ../node_modules

@burtonator
Copy link

I also need to note that moving the node_modules temporarily out of the way is a really bad work around as it causes IntelliJ to go to 100% and needs to re-index all my modules for every build.

@burtonator
Copy link

Also, an sub -project with only one .ts file (empty) still generates errors as typescript tries to load modules in its type map from the ../node_modules

@julkwiec
Copy link

julkwiec commented Jun 4, 2019

I have exactly the same issue as @burtonator and @leemhenson. Tried every possible combination of compilerOptions.typeRoots and compilerOptions.types, but the TS compiler keeps including ../../node_modules/@types no matter what I do.

@kvedantmahajan
Copy link

 "compilerOptions": {
       "types" : []
   }

Will do the job.

@akomm
Copy link

akomm commented Jan 10, 2020

 "compilerOptions": {
       "types" : []
   }

Will do the job.

Will not do the job (fully). You should read documentation for typeRoots and types. It only works for global modules, not imported. For imported modules, you have to use paths and baseUrl.

Either the docs are not correct, I did not understand them, or there is bug, because using it does not seem to restrict module resolution.

I have the following set in an inner project's tsconfig.json:

{
  "compilerOptions": {
    "strict": true,
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "lib": ["dom", "es2017"],
    "jsx": "react",
    "typeRoots": ["./node_modules/@types"],
    "baseUrl": ".",
    "paths": {
      "*": ["./node_modules/*"]
    }
  },
  "include": ["src"]
}

Packages from parent/node_modules are still resolved.

Used typescript 3.7.4.

@RyanCavanaugh RyanCavanaugh added this to the TypeScript 3.9.0 milestone Jan 10, 2020
@kvedantmahajan
Copy link

kvedantmahajan commented Jan 20, 2020

@leemhenson I should have elaborated my answer a bit more because the setup also matters. I commented because I had a similar setup. So please evaluate yourself for this.

First of all, I use yarn workspaces. What yarn as a package manager does is to hoist the packages automatically to the root. Thus, maintaining a central version for all sub-projects. So a sub-project doesn't only fetch from the parent. npm does a similar thing by --hoist flag but I have little experience in production setups.

Second, if for some reason you do have a separate version of the same library for one sub-project then you SHOULD see two entries in IntelliSense.

Third, if out of all the bad initial setups and to quickly calm down two entries to one, my earlier answer will do the work. How?

 "compilerOptions": {
       "types" : []
   }

If you specify the above inside a sub-project's tsconfig.json, then you are basically stating explicitly that "Hey! I'm in charge of specifying types package(s)". In this case, I specify empty array which means typescript compiler will suppress any types from this particular sub-project.

@akomm pay attention

More from Typescript documentation -

A types package is a folder with a file called index.d.ts or a folder with a package.json that has a types field.

Specify "types": [] to disable automatic inclusion of @types packages.

@akomm
Copy link

akomm commented Jan 20, 2020

@kushalmahajan
Thanks for elaborating the answer so others understand when it fixes their problems and when not :)

There is however no reason to quote me the docs, I recommended to check, because elaborating the "it does the job"-answer thrown at an issue is not going to retrospectively make the answer valid.

Specifically the part following the quote is important.

@kvedantmahajan
Copy link

@akomm My purpose to quote you is obvious since you quoted me in the thread and mentioned something which is not a fact.

Please do read my replies and official docs again. I would not mind replying to objectivity.

@akomm
Copy link

akomm commented Jan 20, 2020

I am not going to continue this pedantic back and forth, one last time...

Quote, this issue opening comment:
#30124 (comment)
I've tried settings types: [] and typeRoots, exclude: ["../node_modules"] etc.
You did not pay attention to it.

Quote, another comment from this issue:
#30124 (comment)
I have exactly the same issue as burtonator and leemhenson. Tried every possible combination of compilerOptions.typeRoots and compilerOptions.types, but the TS compiler keeps including ../../node_modules/@types no matter what I do.
You did not pay attention to it.

Your reply on this:

 "compilerOptions": {
       "types" : []
   }

Will do the job.

I stated, that this is incorrect (plus explanation).

You retrospectively particularized your statement turning it from a broad solution to a specific solution. This does not make your (still unchanged) reply valid and my answer to it invalid.

My last comment on this...

@RyanCavanaugh RyanCavanaugh added the Rescheduled This issue was previously scheduled to an earlier milestone label May 20, 2020
@sly010
Copy link

sly010 commented Jun 4, 2020

This is still an issue as of 3.9.3.

@sly010
Copy link

sly010 commented Jun 4, 2020

Correction. In my case "types" : [] does solve the problem.
I originally was placing it outside of compilerOptions.

A few observations:

  1. Without types:[] nodejs is trying to resolve a bunch of typings implicitly. In my case it all starts with:
======== Resolving type reference directive 'estree', containing file '/Users/sly/Work/foo/bar/frontend/__inferred type names__.ts', root directory '/Users/sly/Work/foo/node_modules/@types'. ========

I don't know what implies estree. It is a dependency of a sibling project.

  1. "classic" module resolution is the default and stays the default for backward compatibility. Maybe TypeScript 4 would a great time to change that?

  2. Even with moduleResolution: "node", half of my filesystem is walked for implied typing modules, but the compilation succeeds.

  3. Setting typeRoots to /dev/null also solves the problem.

It seems the root issue is how the default typeRoots is calculated combined with "classic" being the default module resolution method.

@rbuckton
Copy link
Member

rbuckton commented Nov 4, 2020

While I can understand not wanting types from a parent node_modules folder to show up in a subproject when there are conflicts, our behavior is mimicking Node's resolution behavior:

Welcome to Node.js v14.7.0.
Type ".help" for more information.
> process.cwd()
'D:\\dev\\scratch\\fp-ts-oom-repro\\subproject'
> require.resolve("fp-ts/lib/Either")
'D:\\dev\\scratch\\fp-ts-oom-repro\\subproject\\node_modules\\fp-ts\\lib\\Either.js'
> require.resolve("fp-ts/lib/HKTv14_1")
'D:\\dev\\scratch\\fp-ts-oom-repro\\node_modules\\fp-ts\\lib\\HKTv14_1.js'
> require("fp-ts/lib/HKTv14_1")
{}
>

As far as I can tell, this behavior is the correct behavior and is not a bug.

@rbuckton rbuckton added Working as Intended The behavior described is the intended behavior; this is not a bug and removed Needs Investigation This issue needs a team member to investigate its status. labels Nov 4, 2020
@rbuckton rbuckton removed the Rescheduled This issue was previously scheduled to an earlier milestone label Nov 4, 2020
@rbuckton rbuckton closed this as completed Nov 4, 2020
@akomm
Copy link

akomm commented Nov 5, 2020

@rbuckton If I understand @leemhenson correct, his issue is that the types package is found locally, but the types from parent node_modules is still used and merged. AFAIK node's behavior is to only go up, when package has not been found locally.

@rbuckton
Copy link
Member

rbuckton commented Nov 5, 2020

My comment was intended to serve as proof that node still navigates up when a part of a package sub-directory isn't found.

@laurent22
Copy link

laurent22 commented Jan 5, 2023

My comment was intended to serve as proof that node still navigates up when a part of a package sub-directory isn't found.

I don't know what Node is doing, but what TypeScript is doing doesn't seem right. In my case it's trying to parse type files and fails with errors like this:

ERROR in /packages/app-cli/node_modules/@types/jest/index.d.ts
[tsl] ERROR in /packages/app-cli/node_modules/@types/jest/index.d.ts(462,62)
      TS1005: ']' expected.

ERROR in /packages/app-cli/node_modules/@types/jest/index.d.ts
[tsl] ERROR in /packages/app-cli/node_modules/@types/jest/index.d.ts(462,65)
      TS1005: ';' expected.

I can't make any sense of these errors, but more importantly why should I care that TypeScript can't parse files that aren't even used by my project? If I move said project to a different place with no parent node_modules, it works just fine.

Assuming this is, anyway, the right way to load packages (also it feels very wrong), at least there should be a clear options to disable this behaviour.

@rbuckton
Copy link
Member

rbuckton commented Jan 5, 2023

These errors look to be coming from a third-party tool (tsl?), not TypeScript.

awong-dev added a commit to SPS-By-The-Numbers/transcripts that referenced this issue Jun 26, 2024
…tion.

Ensure all auth_code guarded functions generate 401s on invalid auth_code.

Do basic test of transcript reading/writing from fake datastore.

Also fix issue where tsc in the functions directory would look up the parent
node_modules for type resolution in ../common.
microsoft/TypeScript#30124 (comment)

This yielded all sorts of hilarity.
awong-dev added a commit to SPS-By-The-Numbers/transcripts that referenced this issue Jun 26, 2024
…tion.

Ensure all auth_code guarded functions generate 401s on invalid auth_code.

Do basic test of transcript reading/writing from fake datastore.

Also fix issue where tsc in the functions directory would look up the parent
node_modules for type resolution in ../common.
microsoft/TypeScript#30124 (comment)

This yielded all sorts of hilarity.
awong-dev added a commit to SPS-By-The-Numbers/transcripts that referenced this issue Jun 26, 2024
…tion.

Ensure all auth_code guarded functions generate 401s on invalid auth_code.

Do basic test of transcript reading/writing from fake datastore.

Also fix issue where tsc in the functions directory would look up the parent
node_modules for type resolution in ../common.
microsoft/TypeScript#30124 (comment)

This yielded all sorts of hilarity.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Working as Intended The behavior described is the intended behavior; this is not a bug
Projects
None yet
Development

No branches or pull requests