45

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. (By a global path, it means that the import won't change its meaning after moving the file into a different location.)

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"]
    }
  }
}
1
  • When you named it styles or @styles, did you mean it is a CSS file? By default, a tsconfig.json doesn't deal with CSS files. Commented Feb 28, 2024 at 0:22

4 Answers 4

74

In the settings.json file, add this line:

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

If this property is removed, the ugly relative auto-import is the default option. Change 'typescript' to 'javascript' if you're currently using JS. To know more about this setting option, hover over 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 in order to distinguish them from external import paths prefixed with @:

{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "~/*": ["./*"]
    }
  },
}
Sign up to request clarification or add additional context in comments.

Comments

36

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';

3 Comments

In my case we had baseUrl: '.' which needed to be updated to baseUrl: './' for Intellisense to pick it up correctly. I hope this helps someone else.
I had to Ctrl+Shift+P "Reaload Window" in order form the change to apply
Thanks, very useful, @NeoZoom.lua feel free to edit/remove this part from the answer I will accept
4

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/**/*"]
}

Comments

0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.