Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Import module mapping / custom path resolution #88

Closed
micene09 opened this issue May 8, 2020 · 20 comments
Closed

Import module mapping / custom path resolution #88

micene09 opened this issue May 8, 2020 · 20 comments

Comments

@micene09
Copy link

micene09 commented May 8, 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?).

@yyx990803
Copy link
Member

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.

@bates64
Copy link
Contributor

bates64 commented May 8, 2020

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

@ais-one
Copy link
Contributor

ais-one commented May 8, 2020

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

@nestarz
Copy link

nestarz commented May 12, 2020

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

@yyx990803
Copy link
Member

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

@aleclarson
Copy link
Member

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

@spikyjt
Copy link

spikyjt commented Aug 25, 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')
      }
    };
    

@axetroy
Copy link

axetroy commented Sep 15, 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

@ynte
Copy link

ynte commented Sep 18, 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/*"
            ]
        }
    },
}

@spikyjt
Copy link

spikyjt commented Sep 18, 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.

@adapap
Copy link

adapap commented Oct 12, 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)
          }
        }
      },
    },
  ],
}

@NWRichmond
Copy link

NWRichmond commented Jan 18, 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.

@jonjanisch
Copy link

@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,
});

@hungdoansy
Copy link

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

@patak-dev
Copy link
Member

@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!

@TotomInc
Copy link

TotomInc commented Jun 7, 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 },
  },
});

@stefumies
Copy link

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

@kfurfles
Copy link

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
  }
})

@JesusTheHun
Copy link

JesusTheHun commented Jun 29, 2021

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

@mecograph
Copy link

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]]) => {
  ...

@github-actions github-actions bot locked and limited conversation to collaborators Jul 22, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests