30

I would like VSCode to IntelliSense the module path so I can access it by click.

For example, after configurating jsconfig.json I'm able to access ./src/styled/index by importing its global path.

But I couldn't figure out how to make it work with an alias @styles

// VSCode Intellisene Works
import { mixins, theme } from 'styles';

// VSCode Intellisene Doesn't work
import { mixins, theme } from '@styles';

enter image description here

My current jsconfig.json:

{
  "compilerOptions": {
    "baseUrl": "./",
    "jsx": "react",
    "paths": {
      "@styles": ["src/styles/index"]
    }
  }
}
Dennis Vash
  • 50,196
  • 9
  • 100
  • 118

5 Answers5

51

In the settings.json file, add this line:

"typescript.preferences.importModuleSpecifier": "non-relative"

If this property is removed, then the ugly relative auto-import is the default option. Simply change 'typescript' to 'javascript' if you're currently using JS. To know more about this setting option, just hover on it like this:

Auto-import for JS/TS in VSCode

(Bonus tip) Prefix ~/ to all internal import paths with the following compiler options in tsconfig.json:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "~/*": ["./*"]
    }
  },
}
Son Nguyen
  • 2,991
  • 2
  • 19
  • 21
  • Notice that its not alias, its an option for absolute references – Dennis Vash Apr 19 '21 at 14:06
  • Thanks @Son Xuan Nguyen - changing that setting worked. For anyone interested, below are my `baseUrl` and `paths` tsconfig.json settings for when you want to support many sub-directories. i.e. `import { PrimaryButton } from '~components/foo/bar/baz'` `baseUrl` is set to `./` and `paths` to `{ "~components/*": ["./src/components/*"] }` – ourmaninamsterdam Feb 25 '22 at 10:46
  • Sweet and simple. Worked perfectly. – Akash Kumar Seth Nov 24 '22 at 17:34
35

Seems I had to restart VSCode.


Javascript (javascript,javascriptreact file types in VSCode)

An example of jsconfig.json file for reference:

{
  "compilerOptions": {
    "baseUrl": "./src",
    "jsx": "react",
    "paths": {
      "@styles": ["styles/index"],
      "@fonts": ["fonts/index"],
      "@components": ["components/index"],
      "@atoms": ["components/atoms/index"],
      "@molecules": ["components/molecules/index"],
      "@organisms": ["components/organisms/index"],
      "@templates": ["components/templates/index"],
      "@icons": ["components/atoms/Icons/index"],
      "@config": ["config/index"],
      "@utils": ["utils/index"],
      "@hooks": ["hooks/index"],
      "@constants": ["constants/index"],
      "@queries": ["queries/index"],
      "@reducers": ["state/store/reducers"],
      "@actions": ["state/store/actions"],
      "@slices": ["state/slices/"],
      "@storybookHelpers": ["../.storybook/helpers"]
    }
  }
}

An example of how styles/index looks like:

export * from './colors';
export * from './GlobalStyle.styles';
export * from './mixins.styles';

// Or
export { COLORS } from './colors';
export { default as GlobalStyle } from './GlobalStyle.styles';
export { default as mixins } from './mixins.styles';

Will allow import (with IntelliSense):

import { COLORS, mixins, GlobalStyle } from '@styles';

For a bonus: aliases.js, which is a helper which I use to define aliases in webpack config files, it helps to not repeat yourself, for example when using the same aliases in storybook and for the application itself.

// Remember to update `jsconfig.json`
const aliases = (prefix = `src`) => ({
  '@actions': `${prefix}/state/store/actions`,
  '@atoms': `${prefix}/components/atoms`,
  '@molecules': `${prefix}/components/molecules`,
  '@organisms': `${prefix}/components/organisms`,
  '@templates': `${prefix}/components/templates`,
  '@components': `${prefix}/components`,
  '@config': `${prefix}/config`,
  '@constants': `${prefix}/constants`,
  '@hooks': `${prefix}/hooks`,
  '@icons': `${prefix}/components/atoms/Icons`,
  '@queries': `${prefix}/queries`,
  '@reducers': `${prefix}/state/store/reducers`,
  '@slices': `${prefix}/state/slices`,
  '@styles': `${prefix}/styles`,
  '@utils': `${prefix}/utils`,
  '@storybookHelpers': `../.storybook/helpers`,
});

module.exports = aliases;

// usage example at .storybook/webpack.config.js file
const path = require("path");
const alias = require(`../src/config/aliases`);

const SRC = "../src";
const aliases = alias(SRC);

const resolvedAliases = Object.fromEntries(
  Object.entries(aliases).map(([key, value]) => [
    key,
    path.resolve(__dirname, value),
  ])
);

module.exports = ({ config }) => {
  config.resolve.modules.push(path.resolve(__dirname, SRC));
  config.resolve.alias = resolvedAliases;
  return config;
};

Typescript (typescript,typescriptreact files)

At tsconfig.json use the compilerOptions.paths option, notice that the paths are relative to baseUrl:

{
  "compilerOptions": {
    "baseUrl": "./",
    "paths": {
      "@components/*": ["components/*"],
      "@config": ["config"],
      "@constants": ["constants"],
      "@hooks": ["hooks"],
      "@styles": ["styles"],
      "$types/*": ["types/*"],
      "@utils": ["utils"]
    }
}

This allows aliases (with IntelliSense), for example:

// Example of hooks/index.ts file
export * from './useLogin';
export * from './useLocalStorage';
export * from './useAuth';

// Usage examples
import {ROUTES} from '@constants';
import {Text} from '@components/atoms';
import {mixins} from '@styles';
import {useLocalStorage} from '@hooks';
Dennis Vash
  • 50,196
  • 9
  • 100
  • 118
3

I had the right configuration as described by the other answers. In VS code I restarted the TypeScript server using Ctrl + Shift + P -> TypeScript: Restart TS server command and it fixed the editor highlighting the import path error.

Just for completeness here is what my tsconfig.json looks like:

{
  "compilerOptions": {
    ...
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src/**/*"]
}
maulik13
  • 3,656
  • 1
  • 25
  • 36
1

As a side note, make sure the include in your jsconfig/tsconfig is pointing to correct paths.

Alex M
  • 2,410
  • 1
  • 24
  • 37
0

For anyone like me who the other answers aren't working for, these are the tsconfig bits that worked for me, in addition to the settings addition in the accepted answer and ensuring you're setting includes/excludes properly:

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

Full credit to this gist: https://gist.github.com/EmilyRosina/eef3aa0d66568754a98382121fefa154

Shawn Erquhart
  • 1,820
  • 2
  • 17
  • 30
  • Please explain what sets you and your situation apart from the one which is handled by the other answers. In which case is your answer helpful where the others are not. – Yunnosch Nov 07 '22 at 22:37