Typescript: Autoimport always imports relative to baseUrl

Created on 10 Nov 2017  路  29Comments  路  Source: microsoft/TypeScript

_From @artaommahe on November 9, 2017 11:38_

  • VSCode Version: 1.18.0
  • OS Version: Windows 10

Steps to Reproduce:

  1. ts project with provided baseUrl
  2. add autoimport for smth from same directories sub-tree
  3. see baseUrl relative import
/// auth/routing.ts
import {MobileStubComponent} from "auth/component/mobile-stub/mobile-stub";

expected import relative to current file

import {MobileStubComponent} from "./component/mobile-stub/mobile-stub";

Reproduces without extensions: Yes

_Copied from original issue: Microsoft/vscode#37928_

Bug Fixed VS Code Tracked

Most helpful comment

@mikfoo I have changed my config from:

         "baseUrl": "./",
         "paths": {
            "src": ["./src"]
         }

to:

         "baseUrl": "./",
         "paths": {
            "src/*": ["src/*"]
        }

and VS Code now imports from src!
You have all my gratitude for helping me solve this irritating issue!

All 29 comments

_From @Martaver on November 9, 2017 20:17_

Also seeing this behavior, in 1.18 and previous, on both manually chosen import fixes and the new auto-import on completion feature.

_From @Martaver on November 9, 2017 20:34_

For me, removing the baseUrl entry from my tsconfig.json file fixed the issue.

@mjbvz would this issue also affect autoimport in JS/JSX? I'd have a few suggestions for the feature, but don't know if this is the correct place for it.

@kumarharsh Yes, they're the same feature.

OK, so I found the feature useful, although a little rough to use because the import paths it produces are not how the rest of the code is written.

Many times, I export code from the index.js file, for example: constants/Widgets/index.js. Then, I import in this style:

import { A, B, C } from 'constants/Widgets';
  • I drop the /index part because it's redundant in JS/TS-based systems, as far as I know.
  • I also drop the extension part for JS files.
  • I use webpack, and it has a nifty feature which let's me define custom module resolutions (resolve.modules)[https://webpack.js.org/configuration/resolve/#resolve-modules], so instead of writing ../../../ui/Input, I can just write ui/Input and keep my code clean. It also allows me to move the component somewhere else in the future without worrying about breaking import paths.

If the vscode solution can take these into account, it'd be awesome.

  • For /index see #19962.
  • We should be dropping the .js extension already.
  • Setting up --rootDirs should make the third part work.

Oh, awesome! I think No. 2 is already working as expected (my mistake to point that out). About No. 3, my project is a JS project, so there's no tsconfig, but a jsconfig is there.

you should be able to set the same options in jsconfig.json as you do in tsconfig.json

@andy-ms I am confused about rootDirs vs paths. I can only get non-relative imports to work using the paths setting.

 "paths": {
      "*": ["*", "src/*"]
    },

Setting rootDirs: ["*", "src"] doesn't seem to change anything in that context. Also I don't quite get what rootDirs is for if you already tell the compiler what to compile with the "include" setting.

And with the paths setting I still have the issue that I reported here

Here's my full tsconfig:

{
  "compilerOptions": {
    "allowJs": true,
    "allowSyntheticDefaultImports": true,
    "baseUrl": ".",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "forceConsistentCasingInFileNames": true,
    "jsx": "react",
    "lib": ["es6", "es7", "esnext", "dom"],
    "module": "esnext",
    "moduleResolution": "node",
    "noEmitOnError": false,
    "noImplicitAny": false,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noUnusedLocals": true,
    "outDir": "build/dist",
    "paths": {
      "*": ["*", "src/*"]
    },
    "plugins": [
      {
        "name": "tslint-language-service"
      }
    ],
    "rootDirs": [".", "src"],
    "skipLibCheck": false,
    "sourceMap": true,
    "strictNullChecks": false,
    "suppressImplicitAnyIndexErrors": true,
    "target": "es6"
  },
  "exclude": ["build", "config-overrides.js", "jest", "scripts"],
  "include": ["src/**/*"]
}

@mhegazy - the rootDirs setting is not working for me.

paths is completely broken in my case

https://github.com/Microsoft/TypeScript/pull/19724 should give multiple imports anyways.. this will address some of these requests..

You find more info about rootDirs and paths mapping in https://www.typescriptlang.org/docs/handbook/module-resolution.html

Is this fully fixed by #19724?

@kumarharsh, @stevematdavies and @0x80 can you give #19724 a try? the fix should be in typescript@next tomorrow.
VSCode ships with an older version of TypeScript. Please see Using Newer TypeScript Versions documentation for more details on updating your VSCode to use a different version of TypeScript.

@mhegazy I did not notice any change in behavior so far.

I'm trying to use ~/ or @src/ imports. The compiler and linter get it, but the path auto-completion in VSCode still messes things up once I hit tab.

I've tried this:

    "rootDirs": [
      "src"
    ],
    "baseUrl": "src",
    "paths": {
      "@src/*": [
        "*"
      ],
      "~/*": [
        "*"
      ]

And this:

    "baseUrl": ".",
    "paths": {
      "@src/*": [
        "src/*"
      ],
      "~/*": [
        "src/*"
      ]
    },

When I try to import the file from src/helpers/fetch, hitting the tab key at ~/helpers/fet completes it to ~/helpers/node-fetch, because that module is one of my projects dependencies.

If I try to import something what has no name relation to one of my dependencies, the tab key simply inserts a tab space. So no auto-completion at all.

@0x80 I made an issue for that: #21067

Is it broken again? I remember 1-1.5 months ago VS code (using 1.19-insider version) had been displaying the picker with 2 choices: relative path and baseurl path. Now it's autoimporting only baseurl derived paths without any prompts.

TS: 2.7.0-dev.20180119
VSCode: 1.19.2 (tried latest insider version too)

@mhegazy @andy-ms this issue seems to be broken again as well. Adding "baseUrk": "." causes all relative import to go from "src/...." when using auto suggestions.

TS: 2.7.0-dev-20180119
VSCode: both the insider and 1.19.2

@travikk can you try again with latest insiders build? #21398 should have a fix for that.

@mhegazy Since 1.20 Visual Studio Code uses the shorter relative path. This is an issue for the project I'm working on since we stated we prefer using the full path, in order to ease refactoring.

How to I tell VS Code to prefer the full path? I can't find documentation about this, and a first glance reading the code the behaviour might be hard-coded.

@guillaumep we had the same issue and fixed it by adding the following in our tsconfig.json under compilerOptions

"paths": {
  "components/*": ["src/components/*"]
}
...

That makes the auto import set the import string to components/YourComponent and it looks at src/components/YourComponent for the file/folder.

@mikfoo All my imports are from 'src', so this workaround would not work.

@guillaumep Actually, we are using src as well (and our imports are src/foo/bar) but I forgot to mention you need to add baseUrl too.

"baseUrl": "./",
"paths": {
  "src/*": ["src/*"]
}
...

@mikfoo I have changed my config from:

         "baseUrl": "./",
         "paths": {
            "src": ["./src"]
         }

to:

         "baseUrl": "./",
         "paths": {
            "src/*": ["src/*"]
        }

and VS Code now imports from src!
You have all my gratitude for helping me solve this irritating issue!

@mjbvz Your solution worked for me as well

Guys, sorry to write in the closed issues, but all my package imports are imported using relative paths ;(

image

This is my tsconfig.json and typescript 2.9.2

"compilerOptions": {
    "target": "esnext",
    "module": "commonjs",
    "moduleResolution": "node",
    "lib": ["es2017", "dom"],
    "jsx": "react",
    "noEmit": true,
    "skipDefaultLibCheck": true,
    "skipLibCheck": true,
    "pretty": true,
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "strictNullChecks": false,
    "experimentalDecorators": true,
    "typeRoots": ["src/shared/models", "node_modules/@types"]
  }

[EDIT] If need be I can create a new issue.

@tomitrescak I believe it is related to #25279. What happens with typescript@next?

@kitsonk yup, the issue is gone! thanks ... now I do not get the auto correct helper with "CMD + ." but I guess that will arrive later ;)

Was this page helpful?
0 / 5 - 0 ratings

Related issues

remojansen picture remojansen  路  3Comments

Antony-Jones picture Antony-Jones  路  3Comments

blendsdk picture blendsdk  路  3Comments

weswigham picture weswigham  路  3Comments

bgrieder picture bgrieder  路  3Comments