Skip to content

Vue 3 Vite Path Aliases ​

When working with Vue 3 and Vite projects, you may encounter issues where path aliases like @/ don't work as expected, leading to cumbersome import paths like:

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

This article explains how to properly configure path aliases in Vue 3 + Vite projects.

Problem: Missing Path Alias Configuration ​

Vite doesn't provide default path aliases like Webpack does. Without proper configuration, the @ alias won't be recognized, causing import errors and making your code less maintainable.

Solution: Configuring Vite and TypeScript ​

1. Basic Vite Configuration ​

The most straightforward solution is to configure the alias in your vite.config.js or vite.config.ts file:

js
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'),
    },
  }
})
ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'
import { fileURLToPath, URL } from 'url'

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: {
      '@': fileURLToPath(new URL('./src', import.meta.url))
    },
  }
})

2. TypeScript Configuration ​

For TypeScript projects, you also need to update your tsconfig.json to resolve the path aliases:

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

3. Multiple Aliases ​

You can define multiple aliases for different directories:

js
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'),
      '@assets': '/src/assets',
      '@components': '/src/components',
      '@stores': '/src/stores',
      '@utils': '/src/utils'
    },
  }
})
json
{
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"],
      "@assets/*": ["./src/assets/*"],
      "@components/*": ["./src/components/*"],
      "@stores/*": ["./src/stores/*"],
      "@utils/*": ["./src/utils/*"]
    }
  }
}

Advanced Configuration ​

Using fileURLToPath for ES Modules ​

For better compatibility with ES modules, use the fileURLToPath approach:

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

export default defineConfig({
  plugins: [vue()],
  resolve: {
    alias: [
      { 
        find: '@', 
        replacement: fileURLToPath(new URL('./src', import.meta.url)) 
      },
      { 
        find: '@assets', 
        replacement: fileURLToPath(new URL('./src/assets', import.meta.url))
      }
    ],
  },
})

Directory Structure Consideration ​

WARNING

Ensure your vite.config.js file is at the same directory level as your src folder. If they're at different levels, you'll need to adjust the path with ../ prefixes.

Common Issues and Solutions ​

1. TypeScript Path Resolution ​

If you're using TypeScript and still seeing "Cannot find module" errors despite correct configuration:

json
{
  "compilerOptions": {
    "moduleResolution": "node",
    "baseUrl": ".",
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["src/**/*.ts", "src/**/*.d.ts", "src/**/*.vue"]
}

2. Include Patterns for Nested Folders ​

Make sure your tsconfig.json includes all necessary files:

json
{
  "include": [
    "src/**/*.ts",
    "src/**/*.vue",
    "src/**/*.d.ts"
  ]
}

3. Dynamic Imports with Aliases ​

For dynamic imports in template attributes, you might need a helper function:

js
// util.js
export const img = (name) => {
  return new URL(`./assets/img/${name}.png`, import.meta.url).href
}

// In component
<script>
import { img } from '@/util'
</script>

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

Best Practices ​

  1. Consistent Configuration: Keep your Vite and TypeScript configurations synchronized
  2. Absolute Paths: Use absolute paths (without . prefix) for better clarity
  3. IDE Support: Some IDEs might require restarting or clearing cache to recognize new aliases
  4. Testing Setup: If using Jest, you'll need to configure module aliases in your Jest configuration as well

Conclusion ​

Setting up path aliases in Vue 3 + Vite projects requires proper configuration in both vite.config.js and tsconfig.json (for TypeScript projects). The most reliable approach is using the fileURLToPath method with import.meta.url for ES module compatibility.

With these configurations, you can replace cumbersome relative imports:

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

With clean, maintainable aliases:

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