156

I have a Vue.js project set up with Vite. Currently, I'm importing a component like this:

import Component from '../../../../components/Component.vue'

But I'd like to reference it like this instead, so I don't have to use long relative paths - just a short alias:

import Component from '@/components/Component.vue'

vite.config.js

import vue from '@vitejs/plugin-vue'

/**
 * https://vitejs.dev/config/
 * @type {import('vite').UserConfig}
 */
export default {
  plugins: [
    vue({
      template: {
        compilerOptions: {
          // ...
        }
      }
    })
  ]
}

Am I missing something? What else should I do?

2
  • have you tried addiing jsconfig.json? I didnt know jsconfig will work with Vue Vite or not but usually I use this with Vue 2 Commented Feb 4, 2021 at 10:29
  • 1
    I solved this issue adding this in paths array inside my tsconfig.json file: "@/*": ["./src/*"] Commented Mar 27, 2023 at 11:52

14 Answers 14

204

Update 2023: solution with TypeScript support

Here is what worked for me (finally):

vite.config.ts

import { fileURLToPath, URL } from "url";
import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: [
      { find: '@', replacement: fileURLToPath(new URL('./src', import.meta.url)) },
      { find: '@assets', replacement: fileURLToPath(new URL('./src/shared/assets', import.meta.url)) },
      { find: '@cmp', replacement: fileURLToPath(new URL('./src/shared/cmp', import.meta.url)) },
      { find: '@stores', replacement: fileURLToPath(new URL('./src/shared/stores', import.meta.url)) },
      { find: '@use', replacement: fileURLToPath(new URL('./src/shared/use', import.meta.url)) },
    ],
  },
});

tsconfig.json

{
  ...
  "compilerOptions": {
    ...
    "paths": {
      "@/*": ["./src/*"],
      "@assets/*": ["./src/shared/assets/*"],
      "@cmp/*": ["./src/shared/cmp/*"],
      "@stores/*": ["./src/shared/stores/*"],
      "@use/*": ["./src/shared/use/*"]
    }
  }
}

Solution for Vue 3 (Composition API)

This solution comes by default from when creating a new project with npm init vue@latest.

import { fileURLToPath, URL } from "url";

import { defineConfig } from "vite";
import vue from "@vitejs/plugin-vue";

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      "@": fileURLToPath(new URL("./src", import.meta.url)),
    },
  },
});

In components use @/:

<script setup>
import HelloWorld from "@/components/HelloWorld.vue";
</script>

Solution for Vue 2 (Options API)

This is what worked for me:

import path from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@/': `${path.resolve(__dirname, 'src')}/`
    }
  }
})

Then in components:

<template>
  <img alt="Vue logo" src="./assets/logo.png" />
  <HelloWorld msg="Hello Vue 3 + Vite" />
</template>

<script>
import HelloWorld from '@/components/HelloWorld.vue'

export default {
  name: 'App',
  components: {
    HelloWorld
  }
}
</script>
Sign up to request clarification or add additional context in comments.

6 Comments

I get a warning when starting the dev server: Unrestricted file system access to "C:/Projects/my-vite-project/src/main.ts" For security concerns, accessing files outside of serving allow list will be restricted by default in the future version of Vite. Refer to vitejs.dev/config/#server-fs-allow for more details.
Heads up: I needed to add a slash before the @ for it to work, because otherwise "that's considered a package". So like this: import HelloWorld from '/@/components/HelloWorld.vue'
This worked for me and I got to remove vite-tsconfig-paths! Thank you. I think you still need to keeping mapping in tsconfig.json for editor intellisense.
I have a problem doing this. When I change the template of the imported component with alias path it doesn't hot reload on save nor on hard reload. I have to restart the vite server to see the change
How can I use dynamically switching between prod and env mode in aliases? I tried this here: resolve: { alias: [ {find: '@auth', replacement: fileURLToPath(new URL( ./src/api/auth/${process.env.NODE_ENV === 'production' ? 'server' : 'mock'}, import.meta.url))} ] ] ... and in my tsconfig.json I added "paths": {"@/*": ["./src/*", "./dist/*"],"@auth/*": ["./src/api/auth/*"] } and I still get a compiler error that my auth service cannot be resolved ts(2307). Any ideas?
|
130

In the vite.config.js file write the below code blocks

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  }
})

1 Comment

If using vite v2.5.0 or higher '@': path.resolve(__dirname, './src'), . Add . before /src
41

Vue 3 Vite TypeScript

vite.config.ts

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': path.resolve(__dirname, './src'),
    },
  }
})

To remove warnings and add hint to download with @/

tsconfig.json

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

1 Comment

nice. thanks you. I alway has warnings by TS because I set the path to "@/*": ["./src"]. haha
11

Unlike webpack, Vite doesn't have @ aliased to src by default. There is discussion of this at the following issue: https://github.com/vitejs/vite/issues/279

Ultimately you need to create an alias:

// vite.config.js 
module.exports = {
  alias: {
    '/@': path.resolve(__dirname, './src')
  }
}

// Your config 
export default {
  alias: {
    '/@': path.resolve(__dirname, './src')
  },
  plugins: [ ... ]
 }

Then you need to use /@ in your files, e.g.:

import foo from '/@foo'

3 Comments

I like your answer, but I don't know how to insert it into mine vite.config.js
Have updated the answer to hopefully give the answer for your config file.
failed to load config from C:\Users\user\PhpstormProjects\prazdnik\vite.config.js Error while running task C:\Users\user\PhpstormProjects\prazdnik:dev with message 'spawn vite ENOENT' error when starting dev server:...
9

I tried most of the above solutions and unfortunately did not work. The following did.

In my jsconfig.json

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

and in my vite.config.js

import { fileURLToPath } from "url";
import path from "path";

import { defineConfig } from "vite";

export default defineConfig({
  resolve: {
    alias: {
      "@": path.resolve(path.dirname(fileURLToPath(import.meta.url)), "src"),
    },
  },
});

Comments

8

It will be easier if you point to the directory without "." (dot) prefix. This way you don't have to use fileURLToPath anymore.

ViteConfig:

import { defineConfig } from "vite"
import vue from "@vitejs/plugin-vue"

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      // instead of writing:
      // fileURLToPath(new URL("./src", import.meta.url))
      // remove "."(dot) prefix from path and write it like below:
      '@': '/src',
      '@assets': '/src/shared/assets',
      '@cmp': '/src/shared/cmp',
      '@stores': '/src/shared/stores',
      '@use': '/src/shared/use'
    }
  },
})

TSConfig:

{
  ...
  "compilerOptions": {
    ...
    "paths": {
      "@/*": ["./src/*"],
      "@assets/*": ["./src/shared/assets/*"],
      "@cmp/*": ["./src/shared/cmp/*"],
      "@stores/*": ["./src/shared/stores/*"],
      "@use/*": ["./src/shared/use/*"]
    }
  }
}

Note: "vite.config" file directory level must be the same as "src folder" otherwise you must point it with "../" prefix in alias.

Comments

4

As October 2023,

I am using vite(4.4.5) + vue(3.3.4) + ts(5.0.2).

This is what I had to do when I start a new project.

vite.config.ts

export default defineConfig({
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src/"),
    },
  },
  plugins: [vue()],
});

The code above would make the vue to compile your vue component and typescript classes. You can run npm run dev and you wouldn't see any error and the page would render.

Although your vs code probably is showing the error and also if you run npm run build that would fail.

src/App.vue:2:24 - error TS2307: Cannot find module '@/components/HelloWorld.vue' or its corresponding type declarations.

src/components/test.ts:2:22 - error TS2307: Cannot find module '@/classes/classA' or its corresponding type declarations. 

The configuration below does the tricky for me.

tsconfig.json

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

The code above I didn't need to add Public neither change anything about moduleResolution.

My App.vue component:

<script setup lang="ts">
import HelloWorld from '@/components/HelloWorld.vue'
</script>

HelloWolrd.vue

<script setup lang="ts">
import { ref } from 'vue'
import myTestClass from '@/components/test';

defineProps<{ msg: string }>()

const count = ref(0)

new myTestClass().myMethod();

My test.ts

import MyClassA from "@/classes/classA";

export default class myTestClass {

Keep in mind vscode configuration as well. VS Code Image

Comments

1

In my Vite 2.7.x

import vue from '@vitejs/plugin-vue'
import path from 'path'
 
...    
...
 resolve: {
   alias: [
      { find: '@', replacement: path.resolve(__dirname, './src') },
      { find: '...', replacement: path.resolve(__dirname, '...') },
      { find: '...', replacement: path.resolve(__dirname, '...') },
      { find: '...', replacement: path.resolve(__dirname, '...') },
   ]
}

Comments

1

In my blog post i describe how to configure this with Vite, TypeScript and Jest: https://divotion.com/blog/how-to-configure-import-aliases-in-vite-typescript-and-jest. For Vite change the vite.config.ts file to:

// vite.config.ts
import { defineConfig } from "vite";
import path from "path";

export default defineConfig({
  resolve: {
    alias: {
      "@": path.resolve(__dirname, "./src"),
    },
  },
});

Comments

1

I encountered similar problems to yours, although I'm working on my React Project using Vite this still works on the Vue project too.

This is my vite.config.ts:

import { defineConfig } from 'vite';
import path from 'path';
// https://vitejs.dev/config/
export default defineConfig({
    resolve: {
        alias: {
            '/@src-pages': path.resolve(__dirname, './src/pages'),
            '/@src-assets': path.resolve(__dirname, './src/assets')
        }
    },
    plugins: [vue()]
});

Don't forget to add "/" before your alias name.

I found this solution from Vite Github Issue: https://github.com/vitejs/vite/issues/279#issuecomment-635646269

Comments

0

Try the below code in 'vite.config.ts' or 'vite.config.js' file

import { resolve } from 'path'

// https://vitejs.dev/config/
export default defineConfig({
  resolve: {
    alias: {
      '@': resolve(__dirname, './src')
    },
  },
  plugins: [vue()],
})

Comments

0

For me the error was solved by changing the path to:

// tsconfig.json

// ...
  "include": [
-    "path/to/something/*.ext", // Remove this
+    "path/to/something/**/*.ext", // Replace with this
  ]
// ...

I got this error because it was not detecting files in nested folders.

Comments

0
  1. In the common ts code, define path resolve function(i.e. img()) using import.meta.url.
  2. Use img() in the vue script.
/src
  /assets/img/
    logo.png
  Util.ts
  App.vue

Util.ts

export const srcRoot = import.meta.url;
export function img(name:string){
  return new URL(`./assets/img/${name}.png`, srcRoot)
}

App.vue

<script>
import {img} from "./Util";
</script>

<template>
<img :src="img('logo')" />
</template>

Comments

-1

This seems to work for me and is shorter:

import {defineConfig} from 'vite';
import laravel from 'laravel-vite-plugin';
import vue from '@vitejs/plugin-vue';
import path from 'path'

export default defineConfig({
    resolve: {
        alias: {
            '@': path.resolve('./resources'),
        }
    },
    plugins: [
        laravel({
            input: 'resources/js/app.js',
        }),
        vue({
            template: {
                transformAssetUrls: {
                    base: null,
                    includeAbsolute: false,
                },
            },
        }),
    ],
});

1 Comment

Shorter, don't mean better. Without __dirname after compiling and punting to some run environment, bet it won't work.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.