319

For example:

import Component from '@/components/component'

In the code I'm looking at it behaves like ../ going up one level in the directory relative to the file path, but I'd like to know more generally what it does. Unfortunately I can't find any documentation online due to the symbol searching problem.

Laser
  • 5,085
  • 4
  • 34
  • 48

8 Answers8

271

The meaning and structure of the module identifier depends on the module loader or module bundler. The module loader is not part of the ECMAScript spec. From a JavaScript language perspective, the module identifier is completely opaque. So it really depends on which module loader/bundler you are using.

You most likely have something like babel-plugin-root-import in your webpack/babel config.

Basically it means from the root of the project.. it avoids having to write things like import Component from '../../../../components/component'

Edit: One reason it exists is because import Component from 'components/component' doesn't do that but instead search in the node_modules folder

Felix Kling
  • 795,719
  • 175
  • 1,089
  • 1,143
Ben
  • 20,737
  • 12
  • 71
  • 115
144

Know it's old, but I wasn't exactly sure how it's defined, so looked it up, came by, dug a little deeper and finally found this in my Vue-CLI (Vue.js) generated Webpack config

resolve: {
    extensions: ['.js', '.vue', '.json'],
    alias: {
    '@': path.join(__dirname, '..', dir)
    }
},

so it's an alias which in this case points to the root of vue-cli generated src directory of the project

Update: As correctly mentioned by @aderchox in the comments, this is a general Webpack feature and not limited to Vue

Can Rau
  • 3,130
  • 1
  • 23
  • 33
  • 1
    Is it possible to use something like this? `'@*': ['client/src/*']` where only the part **after** `@` is taken, so that I can do `import X from '@components/x` and it correctly tries to access `client/src/components/x`? TS + VSCode already allows that in this exact form in tsconfig.json, however webpack errors with `Can't resolve '@components/x' in 'client/src/'`. When I change it to your solution and the import paths to `import X from '@/components/x'` it immediately starts working, so the paths are otherwise correct. – Qwerty Sep 30 '19 at 17:09
  • @Qwerty No idea, don't know the @* thing didn't know it exists in VSCode, so can't help – Can Rau Sep 30 '19 at 17:16
  • 2
    I use this solution too and I'd like to emphasize that this is vue-agnostic and can be done in "any setup that uses Webpack". (because making vue.js a blue link in the answer might make some folks ignore this answer). – aderchox Apr 27 '22 at 07:29
  • 1
    Your of course right @aderchox, thank you I added it to the answer to clarify – Can Rau Apr 27 '22 at 21:05
43

To make Ben's answer more comprehensive:

First you need to add babel-plugin-root-import in your devDependencies in package.json (If using yarn: yarn add babel-plugin-root-import --dev). Then in your .babelrc add the following lines into plugins key:

"plugins": [
[
  "babel-plugin-root-import",
  {
    "rootPathPrefix": "@"
  }
]
]

Now, you can use @. For example:

Instead of

import xx from '../../utils/somefile'

You Can

import xx from '@/utils/somefile'

LM I
  • 3
  • 1
Ali MasudianPour
  • 14,329
  • 3
  • 60
  • 62
  • I added the plugin to my devdependencies but I have no .babelrc . I even created it in the root ,but still does not work? I just have babel.config.js – Kick Buttowski Feb 20 '20 at 04:22
19

As said above, this feature is not in JS by default. You have to use a babel plugin to enjoy it. And its job is simple. It allows you to specify a default root source for your JS files and helps you map your file imports to it. To get started install through either npm:

npm install babel-plugin-root-import --save-dev

or

yarn add babel-plugin-root-import --dev

Create a .babelrc in the root of your app and configure these settings to your taste:

{
  "plugins": [
    ["babel-plugin-root-import", {
      "rootPathSuffix": "the-preferred/root/of-all-your/js/files",
      "rootPathPrefix": "@"
    }]
  ]
}

With the config above, you can simply import from that source like:

import Myfile from "@/Myfile" 

without doing all this funky stuff:

"/../../../Myfile"

Note that you can also change the symbol to anything like "~" if that floats your boat.

icc97
  • 11,395
  • 8
  • 76
  • 90
Wale
  • 1,321
  • 16
  • 11
12

I am using VS code to build react native Apps.

What you need is:

  1. create a jsconfig.json under root path of your App enter image description here
  1. in your jsconfig.json, add the following code:
{
  "compilerOptions": {
    "baseUrl": ".",
    "target": "ES6",
    "module": "commonjs",
    "paths": {
      "@/*": ["src/*"],
      "@components/*": ["src/components/*"],
      "@core/*": ["src/core/*"]
    }
  },
  "exclude": ["node_modules"]
}

basically like "shortcut" : ["abs_path"]

Yukulélé
  • 15,644
  • 10
  • 70
  • 94
Daniel Hua
  • 153
  • 2
  • 8
11

In case you are using Typescript, you could achieve this by simply using your tsconfig.json like this:

{
  "compilerOptions": {

    ...

    "baseUrl": ".",
    "paths": {
      "@lib/*": ["app/lib/*"]
    }
  },
}
Johnny Kontrolletti
  • 727
  • 1
  • 10
  • 22
2

// @ is an alias to /src

Inspired by Can Rau's answer I made a similar discovery in my src/views/Home.vue file. This file was created with the latest (July 2021, Ubuntu 20.04) versions: npx @vue/cli create myfirstvue --default.

I "inferred" it was /src but wanted to know why, because Ben's accepted answer said it would be the root of my project, which in fact is the parent, of /src.

Here is Home.vue:

...
<script>
// @ is an alias to /src
import HelloWorld from '@/components/HelloWorld.vue'
</script>

It is defined by Vue Webpack template, which I learned from this other SO answer.

John
  • 6,433
  • 7
  • 47
  • 82
1

It is a way of remapping module paths, not part of the ES itself, you have to use babel import feature.

mabreu0
  • 80
  • 2
  • 8