Skip to content

Declarations are unexpectedly used from node_modules in parent directory #30124

Closed
@leemhenson

Description

@leemhenson

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

Activity

j-oliveras

j-oliveras commented on Feb 27, 2019

@j-oliveras
Contributor

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

leemhenson

leemhenson commented on Feb 27, 2019

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

and variants have no effect.

burtonator

burtonator commented on Apr 30, 2019

@burtonator

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

burtonator commented on Apr 30, 2019

@burtonator

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

burtonator commented on Apr 30, 2019

@burtonator

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

julkwiec commented on Jun 4, 2019

@julkwiec

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

kvedantmahajan commented on Jun 16, 2019

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

Will do the job.

akomm

akomm commented on Jan 10, 2020

@akomm
 "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.

kvedantmahajan

kvedantmahajan commented on Jan 20, 2020

@kvedantmahajan

@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

akomm commented on Jan 20, 2020

@akomm

@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

kvedantmahajan commented on Jan 20, 2020

@kvedantmahajan

@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.

15 remaining items

removed
RescheduledThis issue was previously scheduled to an earlier milestone
on Nov 4, 2020
akomm

akomm commented on Nov 5, 2020

@akomm

@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

rbuckton commented on Nov 5, 2020

@rbuckton
Contributor

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

laurent22 commented on Jan 5, 2023

@laurent22

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

rbuckton commented on Jan 5, 2023

@rbuckton
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Working as IntendedThe behavior described is the intended behavior; this is not a bug

Type

No type

Projects

No projects

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @leemhenson@burtonator@sly010@DanielRosenwasser@laurent22

      Issue actions

        Declarations are unexpectedly used from node_modules in parent directory · Issue #30124 · microsoft/TypeScript