Subscribe on changes!

Import module mapping / custom path resolution

avatar
May 8th 2020

Taking inspiration from the following:

...would be nice to have a custom path mapping, just to have a sexier import paths, ex:

// example.ts
import { Store, GlobalModule, AppModule } from "@app-utils/store-manager";
import { ICenter } from "@app-rest/centers";
import { ICompany } from "@app-rest/companies";
import MyModal from "@app-components/my-modal/my-modal.vue";

...instead of relative paths like:

import { Store, GlobalModule, AppModule } from "../../store-manager";
import { ICenter } from "../../../centers";
...

Currently on Vue CLI 3 (Webpack), to achieve this feature, i'm using tsconfig-paths-webpack-plugin ...but for a non-typescript related builder like vite i suggest to go for a config file (and maybe an API to extend this behaviour?).

avatar
May 8th 2020

Internally there is already a resolver that does this (see vitepress' resolver for example)

But we probably will provide an easier to use format in the config.

avatar
May 8th 2020

I propose supporting import maps rather than using special vite-specific config.

avatar
May 8th 2020

For using import maps please consider also the discussions below...

avatar
May 12th 2020

Don't know if it can help but I just made a package manager (here) that use import maps spec resolver.

avatar
May 12th 2020

alias option is now supported via the config file. Will consider supporting import maps if it gets closer to being standardized.

avatar
Aug 6th 2020

I've published vite-tsconfig-paths to solve this problem: https://github.com/aleclarson/vite-tsconfig-paths

Also, retweet this if you'd like: https://twitter.com/alecdotbiz/status/1291095881262010371

avatar
Aug 25th 2020

For anyone finding this and wondering how to set up Typescript paths in a Vite project:

  • You must set up your paths with leading slashes, e.g.
        "paths": {
          "/@/*": [
            "src/*"
          ]
        }
    
  • Add your paths to the alias property in vite.config.js in the root of your project, e.g.
    const path = require('path');
    
    module.exports = {
      alias: {
        '/@/': path.resolve(__dirname, 'src')
      }
    };
    
avatar
Sep 15th 2020

For anyone finding this and wondering how to set up Typescript paths in a Vite project:

  • You must set up your paths with leading slashes, e.g.
        "paths": {
          "/@/*": [
            "src/*"
          ]
        }
    
  • Add your paths to the alias property in vite.config.js in the root of your project, e.g.
    const path = require('path');
    
    module.exports = {
      alias: {
        '/@/': path.resolve(__dirname, 'src')
      }
    };
    

ham.... This did not work for me. 😥

import { defineComponent } from "vue";
import { api } from "@/api"; // error here
avatar
Sep 18th 2020

ham.... This did not work for me. disappointed_relieved

import { defineComponent } from "vue";
import { api } from "@/api"; // error here

You need to start with the forward slash in your import statement as well

import { api } from "/@/api";

As an addition the comment by @spikyjt: I needed to set the baseUrl option in my tsconfig.json to make the alias be recognized by typescript. So I think the minimal config to get started with this is:

{
    "compilerOptions": {
        ..
        "baseUrl": ".",
        "paths": {
            "/@/*": [
                "src/*"
            ]
        }
    },
}
avatar
Sep 18th 2020

@ynte thanks for filling in the gaps. @axetroy I'd written this from the point of view of someone who already used paths with typescript and therefore would know that baseUrl is a requirement to use paths. I wasn't being thorough enough to give a complete example for someone starting from scratch and unfamiliar with paths!

FYI, the @ isn't required, it is just a convention for starting path aliases, to help distinguish from absolute paths. It would be ideal if Vite could support a custom prefix for aliases or at least support @ as well as /, to fit with the convention.

avatar
Oct 12th 2020

To those who may still be looking for a solution to this problem, I have found a way to use customizable aliases with little complication.

vite.config.ts

const pathAliasMap = {
  '@/': '/src/',
  '@components/': '/src/components/',
  '@views/': '/src/views/',
}

export default {
  resolvers: [
    {
      alias(path: string) {
        for (const [slug, res] of Object.entries(pathAliasMap)) {
          if (path.startsWith(slug)) {
            return path.replace(slug, res)
          }
        }
      },
    },
  ],
}
avatar
Jan 18th 2021

After trying most of the above recommendations, this is the only configuration that allowed me to map ~ to ./src:

  1. vite.config.ts:
import { defineConfig } from "vite";
import { resolve } from "path";

export default defineConfig({
  resolve: {
    alias: {
      "~": resolve(__dirname, "src"),
    },
  },
  // ...other config,
});
  1. tsconfig.json:
{
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "~/*": ["./*"]
    }
  },
}

[June 21, 2021] updated vite.config.ts to agree with the new resolve.alias convention discussed in the next comment.

avatar
Feb 23rd 2021

@NWRichmond thanks that worked for me.

However, I see this warning when starting vite dev mode (vite 2.0.1):

(!) "alias" option is deprecated. Use "resolve.alias" instead.

Changing it to the following removed the warning:

import { defineConfig } from "vite";
import { resolve } from "path";

export default defineConfig({
  resolve: {
    alias: {
      "~": resolve(__dirname, "src"),
    },
  },
  // ...other config,
});
avatar
Mar 23rd 2021

I'm not using TypeScript, but Javascript absolute imports instead. No alias configured. I just have "baseUrl": "./src/" in jsconfig.json and I do things like import {someComponent} from "components/SomeComponent";

Does anyone have ideas how to make paths work automatically?

I can do like this

import { defineConfig } from "vite";
import { resolve } from "path";

export default defineConfig({
  resolve: {
    alias: {
      "components/": resolve(__dirname, "src/components/"),
      "utils/": resolve(__dirname, "src/utils/"),
      "actions/": resolve(__dirname, "src/actions/"),
    },
  },
  // ...other config,
});

But it doesn't look so good to me

avatar
Mar 23rd 2021

@hungdoansy comments on closed issues are probably going to get ignored. Please start a GitHub Discussion or join the chat at Vite Land to ask questions. Thanks!

avatar
Jun 7th 2021

@hungdoansy something like this will probably help you:

// vite.config.ts
import path from 'path';
import { readdirSync } from 'fs';

const absolutePathAliases: { [key: string]: string } = {};

const srcPath = path.resolve('./src');
// Don't forget to adjust the regex here so it can include .vue, .js, .jsx, etc... files from the src/ folder.
// In my case, I'm writing React + TypeScript so the regex find files with .ts?(x) extensions only.
const srcRootContent = readdirSync(srcPath, { withFileTypes: true }).map((dirent) => dirent.name.replace(/(\.ts){1}(x?)/, ''));

srcRootContent.forEach((directory) => {
  absolutePathAliases[directory] = path.join(srcPath, directory);
});

export default defineConfig({
  resolve: {
    alias: { ...absolutePathAliases },
  },
});
avatar
Jun 14th 2021

With Vue3 Typescript and Viite 2.3.7 I still have not got any of these solutions to work

avatar
Jun 19th 2021

I'm using with react + TS. that works for me

{
 "compilerOptions": {
  "baseUrl": ".",
  "paths": {
      "~/*": ["./src/*"],
      "@core/*": ["./src/core/*"],
      "@authentication/*": ["./src/modules/authentication/*"]
    }
 }

import {
  compilerOptions
} from './tsconfig.json'

import { defineConfig } from 'vite'
import reactRefresh from '@vitejs/plugin-react-refresh'
import { resolve } from 'path';

const alias = Object.entries(compilerOptions.paths)
  .reduce((acc,[key, [value]]) => {
  const aliasKey = key.substring(0, key.length - 2)
  const path = value.substring(0, value.length - 2)
  return {
    ...acc,
    [aliasKey]: resolve(__dirname, path)
  }
}, {})

export default defineConfig({
  plugins: [reactRefresh()],
  resolve: {
    alias
  }
})
avatar
Jun 29th 2021

There is a plugin for that now : https://github.com/aleclarson/vite-tsconfig-paths . No more workaround :) the default config works just fine.

avatar
Jul 6th 2021

Unfortunately the plugin @JesusTheHun mentioned didn't work for me but the solution @kfurfles did with slight modifications. I had to change the compilerOptions a bit:

import config from './tsconfig.json'

const alias = Object.entries(config.compilerOptions.paths)
  .reduce((acc,[key, [value]]) => {
  ...