Typescript: TS Paths not working with index.ts when using a wildcard - more explained inside

Created on 3 Sep 2018  ·  18Comments  ·  Source: microsoft/TypeScript

Hi,

I am using paths to point to another project ( I am using lerna), anyway, I have the following path setup.

    "paths": {
      "@test/pkg2/*": [
        "./packages/pkg2/src/*"
      ],

The problem is that if I do the following, I get an error saying cannot find module.

import {Something} from "@test/pkg2"; // <<<<<<< This errors HERE HERE
import {TestMe} from '@test/pkg2/item/testme' << This is fine

The above error can be fixed by appending index.ts after the /pkg2, but it should know the default package name is index.ts if not is specified.

I can, of course, change the paths to

  "@test/pkg2": [
    "./packages/pkg2/src"
  ],

but now, of course, it complains about not finding testme (see above). The only way I was able to get it to work was by adding both the paths, but is this really correct ?

So, here is what i ended up with, its a lot more code.

   "paths": {
      "@test/pkg2/*": [
        "./packages/pkg2/src/*"
      ],
      "@test/pkg2": [
        "./packages/pkg2/src/"
      ]
    }
Question

Most helpful comment

Any plans on this issue? In ES6, having an index.js file in a folder lets you perform an import from the folder implicitly without specifying the index.js. Why not to follow specs, as it is widely used?

All 18 comments

Folders (or index posing "as" a folder) and files are treated separately in path mappings. Generally this is preferred since it gives you more control over whether or not you want to be able to import a sub-module of some given path (frequently you don't)

@RyanCavanaugh didn't got what should we do to avoid the issue? I've been using WebStorm before and it worked fine. So I was very surprised I have bugged import resolution with proper jsconfig.json:

{
  "compilerOptions": {
    "target": "esnext",
    "checkJs": false,
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": [
    "./src/**/*",
    "./test/**/*"
  ]
}

Any plans on this issue? In ES6, having an index.js file in a folder lets you perform an import from the folder implicitly without specifying the index.js. Why not to follow specs, as it is widely used?

Would love to see how jest handles this, or something similar.
ie:

"moduleNameMapper": {
  "^@/(.*)$": "<rootDir>/src/$1"
}

Edit: I guess I'm seeing that vue spins up with a tsconfig.json that includes:

"paths": {
  "@/*": [
    "src/*"
  ]

I'm just not getting proper definition following in VSCode's IDE. I don't remember which original story deferred me to here (it's been a couple deep now), but it sounded like VSCode said it was in the hands of TypeScript.

edit2: TypeScript compiles fine, but for whatever reason using the find definition of VSCode just points to a shims-vue.d.ts file instead of the imported file when clicking on the import path or imported class/component.

Hm, I thought I had a similar issue, but then I realized that I the error was coming from not removing my lib folder before rebuilding.
I did create a file.ts and then changed it to file/index.ts. The previous file.ts was still there in my lib folder and was messing everything up, because importing file was conflicting between the folder and the previous file who was selected by default.

Hope that helps!

Got here following this issue https://github.com/Microsoft/vscode/issues/57096

I have a similar problem where vscode can't resolve index.js on a jsconfig.json wildcard defined path. Will this ever be resolved?

This issue has been marked as 'Question' and has seen no recent activity. It has been automatically closed for house-keeping purposes. If you're still waiting on a response, questions are usually better suited to stackoverflow.

Why closed? Is the issue is fixed for VSCode?

FWIW I just got stuck on this but I think I solved it. Adding "module": "commonjs" to compilerOptions got it working for me.

My jsconfig.json:

{
  "compilerOptions": {
    "target": "es2017",
    "allowSyntheticDefaultImports": false,
    "baseUrl": ".",
    "paths": {
      "app/*": ["src/app/*"],
    },
    "jsx": "react",
    "checkJs": true,
    "module": "commonjs"
  },
  "exclude": ["node_modules", "dist"]
}

vscode insiders 1.37.0.

Same issue with vue cli, has src/* mapped to @/. it compiles fine but upon "go to definition" of an import, it shows either a shim, or a declared interface it can find.

FWIW I just got stuck on this but I think I solved it. Adding "module": "commonjs" to compilerOptions got it working for me.

My jsconfig.json:

{
  "compilerOptions": {
    "target": "es2017",
    "allowSyntheticDefaultImports": false,
    "baseUrl": ".",
    "paths": {
      "app/*": ["src/app/*"],
    },
    "jsx": "react",
    "checkJs": true,
    "module": "commonjs"
  },
  "exclude": ["node_modules", "dist"]
}

Yeah, that helped 🎉

FWIW I just got stuck on this but I think I solved it. Adding "module": "commonjs" to compilerOptions got it working for me.

My jsconfig.json:

{
  "compilerOptions": {
    "target": "es2017",
    "allowSyntheticDefaultImports": false,
    "baseUrl": ".",
    "paths": {
      "app/*": ["src/app/*"],
    },
    "jsx": "react",
    "checkJs": true,
    "module": "commonjs"
  },
  "exclude": ["node_modules", "dist"]
}

Thanks @jonlambert, that worked like a charm! :clap:

Adding "module": "commonjs" doesn't work in my case :disappointed:

jsconfig.json

{
  "compilerOptions": {
    "baseUrl": "src",
    "module": "commonjs"
  },
  "include": ["src"],
  "exclude": ["node_modules"]
}

Restarting vs code works :smiley:

I get it, change value of "module" in tsconfig.json to "commonjs", works for me.
we can trace this by using "tsc --traceResolution" to see where typescript is looking for .

A fair warning for anyone with similar issue as I had. My jsconfig.json:

{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@api/*": ["api/*"],
            "@components/*": ["components/*"],
            "@redux/*": ["redux/*"],
            "@slices/*": ["redux/slices/*"],
        },
        "module": "commonJS"
    },
    "exclude": [
        "build",
        "node_modules",
        "public"
    ],
}

Now in some JavaScrpt file, this will not work:

import { fetch } from '@api';

But the following will:

import { fetch } from '@api/index';

The reason is quite simple although took me a while to realize it. This line:

        "@api/*": ["api/*"],

Only works for @api/* (the forward slash is the most crucial here). Defining another path, e.g. "@api": ["api/index.js"], will allow you to import from @api without specifying index.

In my project to solve this problem i've added
"moduleResolution": "node".
Also fixes monorepo issues.

Adding multiple entries solved it for me (one with /* and one without /*)

"module": "commonjs"
image

Was this page helpful?
0 / 5 - 0 ratings

Related issues

CyrusNajmabadi picture CyrusNajmabadi  ·  3Comments

kyasbal-1994 picture kyasbal-1994  ·  3Comments

manekinekko picture manekinekko  ·  3Comments

fwanicka picture fwanicka  ·  3Comments

DanielRosenwasser picture DanielRosenwasser  ·  3Comments