Vite: alias '@' to path.resolve(__dirname, './src') is not working

Created on 27 May 2020  ·  15Comments  ·  Source: vitejs/vite

Describe the bug

Alias { '@': path.resolve(__dirname, './src') } is not working.

Reproduction

project structure:

vite.config.js
src
├── app.js
├── index.js

vite.config.js:

const path = require('path');

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

src/index.js

import { Foo } from '@/app';

Got error in vite:

[vite] Failed to resolve module import "@/app"

System Info

  • required vite version: 0.17.0
  • required Operating System: Linux
  • required Node version: 14.3.0
pending triage

Most helpful comment

You have to import as /@/xxx, it cannot start with @ because that's considered a package.

Note Vite is not a bundler - it's a dev server. Any request not starting with / or . is considered a module dependency request. All other requests must be valid HTTP requests (start with / or .).

This also means you can NOT directly import from fs paths like in webpack:

import foo from '/some/fs/path/foo.js'

This doesn't make sense in Vite. So anything starting with / is a request from the root where the server is serving.

All 15 comments

Vite alias don't work like webpack does.
You need to use resolvers to do what you want to do.

@remyz17
I tried this code, but it doesn't work either:

const path = require('path');
const srcPath = path.resolve(__dirname, './src');

module.exports = {
  resolvers: [{
    alias (id) {
      if (id.startsWith('@/')) {
        return path.join(srcPath, id.slice(2));
      }
    }
  }],
};

I guess you need to implement this 2 functions.
requestToFile and fileToRequest

Take a look at this code
https://github.com/vuejs/vitepress/blob/master/src/node/resolver.ts#L19

i tried to do it and it's not fully working.
For exemple it don't work inside vue template: <img src="/@/..." />

module.exports = {
  outDir: '../app/static',
  resolvers: [{
    requestToFile: publicPath => {
      if (publicPath.match(/^\/@\//)) {
        return path.join(srcPath, publicPath.replace(/^\/@\//, ''))
      }
    },
    fileToRequest: filePath => {
      if (filePath.startsWith('/src')) {
        return `/@/${path.relative(srcPath, filePath)}`
      }
    }
  }]
}

I noticed that we can not use @/ because it’s recognised as a node module so I used /@/

@remyz17
This not works for me. In my case, the function fileToRequest is not even be called, and I'm still figuring out why.

@remyz17

This not works for me. In my case, the function fileToRequest is not even be called, and I'm still figuring out why.

Send your vite config so i can take a look

@remyz17
OK, here is my config:

// vite.config.ts
import * as path from 'path';

import * as reactPlugin from 'vite-plugin-react';

import type { UserConfig } from 'vite';

const srcPath = path.resolve(__dirname, './src');

const config: UserConfig = {
  jsx: 'react',
  alias: {
    'exenv': 'exenv-esm',
    'prop-types': 'es-react/prop-types.js',
  },
  resolvers: [{
    fileToRequest (filePath) {
      console.log('@@@', filePath);
      if (filePath.startsWith(srcPath)) {
        return `/@/${path.relative(srcPath, filePath)}`;
      }
    },
    requestToFile (publicPath) {
      if (publicPath.startsWith('/@/')) {
        return path.join(srcPath, publicPath.replace(/^\/@\//, ''));
      }
    },
  }],
  root: './src',
  plugins: [reactPlugin],
};

export default config;

I think we probably will eventually provide an easier way to alias src directories. If your resolver is not working, it's better to provide a full reproduction instead of a single config file.

btw you don't need an alias like that... you can just do /main.js because that's the server root.

@yyx990803
that should work, but I personally don't like to do that, because a path starts with / make me thought it's a file under the / folder of my file system.
And could you review my code of the resolver, am I doing something wrong or it's a bug of vite?

It's a bug. It's fixed in 801951e but it also adds an easier way to alias a directory so you can just do

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

@yyx990803
Still doesn't work for after I upgrade vite to v0.18.0.
https://codesandbox.io/s/vite-src-alias-demo2-lzpm0

You have to import as /@/xxx, it cannot start with @ because that's considered a package.

Note Vite is not a bundler - it's a dev server. Any request not starting with / or . is considered a module dependency request. All other requests must be valid HTTP requests (start with / or .).

This also means you can NOT directly import from fs paths like in webpack:

import foo from '/some/fs/path/foo.js'

This doesn't make sense in Vite. So anything starting with / is a request from the root where the server is serving.

Heads up I was porting an app and /@/xxx aliasing working for all code but the assets did not work.

Was this page helpful?
0 / 5 - 0 ratings