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'