14

What can resolve.alias do? It doesn't resolve the path below:

// vite.config.js
import { defineConfig } from 'vite'
import path from 'path'

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

In my HTML:

<img src="@/assets/images/sample-1.jpg">

Error in the browser Console:

GET http://localhost:3000/@/assets/images/sample-1.jpg 
Failed to load resource: the server responded with a status of 404 (Not Found)
client:180 [vite] connecting...
client:202 [vite] connected.

Any ideas how to do it correctly?

Run
  • 54,938
  • 169
  • 450
  • 748
  • 1
    * As a note for people coming these days, I think using @ as an alias is probably a bad idea as many npm packages now include @ as a prefix and so you'll need to work around that. Perhaps use ~ which for aspnet devs has always meant 'the root'. – James White May 05 '23 at 19:01

7 Answers7

14

npm install @rollup/plugin-alias --save-dev

or

yarn add -D @rollup/plugin-alias

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

const projectRootDir = resolve(__dirname);

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    alias({
      entries: [
        {
          find: '@',
          replacement: resolve(projectRootDir, 'src')
        }
      ]
    })
  ],
  server: {
    host: '0.0.0.0',
    port: 10086, 
    open: false,
    cors: true, 
  },
  build: {
    outDir: 'dist',
  }
})

or


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

const projectRootDir = resolve(__dirname);

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    alias(),
    vue()
  ],
  resolve: {
    alias: {
      "@": resolve(projectRootDir, "src"),
    },
  },
  server: {
    host: '0.0.0.0',
    port: 10086,
    open: false, 
    cors: true, 
  },
  build: {
    outDir: 'dist',
  }
})


keyboard_wang
  • 156
  • 2
  • 4
13

Looks like no additional plugins needed (vite 3.1.0), configuration vite.config.js:

import { defineConfig } from 'vite';
import * as path from 'path';

export default defineConfig({
...
    resolve: {
        alias: [
            { find: '@', replacement: path.resolve(__dirname, 'src') },
        ],
    },
...
});

tsconfig.json

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

Also don't forget about linting, eslint also should know about aliases. Just install eslint plugin eslint-import-resolver-alias and define it in eslint config .eslintrc.js

module.exports = {
...
    settings: {
        'import/resolver': {
            node: {
                extensions: ['.js', '.vue', '.ts', '.d.ts'],
            },
            alias: {
                extensions: ['.vue', '.js', '.ts', '.scss', '.d.ts'],
                map: [
                    ['@/components', './src/components'],
                    ['@/pages', './src/pages'],
                    ['@/router', './src/router'],
                    ['@/store', './src/store'],
                    ['@/styles', './src/styles'],
                    ['@/types', './src/types'],
                    ['@/utils', './src/utils'],
                ],
            },
        },
    },
...
};

As you can see I defined aliases for every folder, it's because i got problem with alias for whole folder src, it throw error for packages started with @ symbol - can't resolve package, but current way works well.

Joyful
  • 813
  • 8
  • 15
3

A simple solution for version 2.7.12 (my current) is to declare alias as an array:

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

export default defineConfig({
  plugins: [ vue() ],
  resolve: {
    alias: [
      { find: '@', replacement: path.resolve(__dirname, './src') },
      { find: '@config', replacement: path.resolve(__dirname, './src/config') },
      { find: '@plugins', replacement: path.resolve(__dirname, './src/plugins') },
      { find: '@views', replacement: path.resolve(__dirname, './src/views') },
      { find: '@mixins', replacement: path.resolve(__dirname, './src/mixins') },
      { find: '@svg', replacement: path.resolve(__dirname, './src/svg') },
      { find: '@models', replacement: path.resolve(__dirname, './src/models') },
      { find: '@components', replacement: path.resolve(__dirname, './src/components') },
    ]
  }
})

You can see the legal format when checking the type:

resolve?: ResolveOptions & {
  alias?: AliasOptions;
};

where AliasOptions is an array of aliases:

export declare type AliasOptions = readonly Alias[] | { [find: string]: string }
widow.dad
  • 39
  • 2
2

For Vite versions >4 , I did two things

firstly, resolved the alias in vite.config.ts

resolve: {
alias: [
    { find: '@', replacement: path.resolve(__dirname, 'src') },
    { find: '@auth', replacement: path.resolve(__dirname, './src/auth') },
],

secondly, added paths to tsconfig.json

  "baseUrl": "src",
  "paths": {
  "@layout/*": ["layout/*"],
  "@lib/*": ["lib/*"],
  "@auth/*": ["auth/*"],
},
0

You can declare these as an object, with keys and values, instead of resolving paths yourself.

A small example:

import { defineConfig } from 'vite';

export default defineConfig({
  ..
  resolve: {
    alias: {
      '@components': '/src/components',
      '@hooks': '/src/hooks',
      '@util': '/src/util',
    },
  },
});
webbm
  • 634
  • 8
  • 18
0

For Vite >=4 and Node >=14 and ESM style, you need to:

  • import resolve function form path module in vite.config.ts file:
    import { resolve } from 'node:path';
    
  • then add below property to object passed to defineConfig function:
    resolve: {
      alias: {
        alias: [{
          find: 'ॐ',
          replacement: resolve(__dirname, 'src')
        }],
      }
    }
    
  • after this, add below property to compilerOptions object in tsconfig.json file:
    "paths": {
      "ॐ/*": ["./src/*"],
    }
    
  • then you will able import other modules easily within deeply nested modules without worrying about . or ..:
    import ErrorBoundary from 'ॐ/component/errorBoundary/ErrorBoundary';
    
harshrathod50
  • 93
  • 1
  • 8
0

It's exhausting to map all @*, so use regex

import { resolve, join } from 'path';
import { defineConfig } from 'vite';

export default defineConfig({
  resolve: {
    alias: [
      { find: /@(.*)/, replacement: join(resolve(__dirname, 'src'), "$1") }
    ]
  }
});

It finds every import @(.*) and replaces it with __dirname/src/$1, whereas $1 is the matching group after @.

For your tsconfig.json, do similar:

{
    "compilerOptions": {
        "paths": {
            "@*": ["./src/*"]
        }
     }
}
Francisco Gomes
  • 1,411
  • 12
  • 13