vite icon indicating copy to clipboard operation
vite copied to clipboard

Native support for tsconfig's paths resolution

Open Exelord opened this issue 3 years ago • 16 comments

Clear and concise description of the problem

By having Typescript integration in Vite, I kind of assumed all tsconfig features would work out-of-the-box. While migrating from Next.js I discovered that Vite is lacking support for paths resolving. I noticed that many of my friends did that as well, although I would be in favour of adding a full typescript features support.

Suggested solution

Add native support for paths resolutions similar to: https://www.npmjs.com/package/vite-tsconfig-paths

Alternative

Document lack of this feature in Typescript section and recommend using: https://www.npmjs.com/package/vite-tsconfig-paths

Additional context

No response

Validations

Exelord avatar Feb 09 '22 20:02 Exelord

I have to say, I also would like to have this :thinking:

So I would not need this anymore in all my projects https://github.com/Shinigami92/quasar-vite/blob/d76b2e7a85a6ada9d0735fbc44931757af86df68/vite.config.ts#L23-L27

Shinigami92 avatar Feb 09 '22 21:02 Shinigami92

TSConfig paths only works for TypeScript / JavaScript modules (semantically). We need the alias for all kinds of resources. So I think it would be confusing to use paths exclusively.

haoqunjiang avatar Feb 10 '22 06:02 haoqunjiang

My solution:

import tsconfig from "./tsconfig.json";

const tsconfigPathAliases = Object.fromEntries(
  Object.entries(tsconfig.compilerOptions.paths).map(([key, values]) => {
    let value = values[0];
    if (key.endsWith("/*")) {
      key = key.slice(0, -2);
      value = value.slice(0, -2);
    }

    const nodeModulesPrefix = "node_modules/";
    if (value.startsWith(nodeModulesPrefix)) {
      value = value.replace(nodeModulesPrefix, "");
    } else {
      value = path.join(__dirname, value);
    }

    return [key, value];
  })
);

Works with my tsconfig.json:

// ...
    "paths": {
      "@/*": ["src/*"],
      "semantic-ui-css": ["node_modules/fomantic-ui-css"],
      "mobx-react": ["node_modules/mobx-react-lite"],
      "lodash": ["node_modules/lodash-es"],
      "markdown-it": ["node_modules/@esm-bundle/markdown-it"]
    }
// ...

Menci avatar Mar 05 '22 14:03 Menci

The feature should explicitly support (and validate it works with) a tsconfig.json with the extends keyword to import a tsconfig.base.json that has paths defined in the base file.

drush avatar Jun 15 '22 00:06 drush

Adding some notes from #10063: tsconfig paths do not work in vite.config.ts, which was closed in favor of this issue.

In addition to the recommended functionality of vite-tsconfig-paths, which only works for the project being built, it would also be ideal to have paths aliases accessible within the execution of vite.config.ts itself.

Enteleform avatar Sep 13 '22 10:09 Enteleform

My solution:

import tsconfig from "./tsconfig.json";

const tsconfigPathAliases = Object.fromEntries(
  Object.entries(tsconfig.compilerOptions.paths).map(([key, values]) => {
    let value = values[0];
    if (key.endsWith("/*")) {
      key = key.slice(0, -2);
      value = value.slice(0, -2);
    }

    const nodeModulesPrefix = "node_modules/";
    if (value.startsWith(nodeModulesPrefix)) {
      value = value.replace(nodeModulesPrefix, "");
    } else {
      value = path.join(__dirname, value);
    }

    return [key, value];
  })
);

Works with my tsconfig.json:

// ...
    "paths": {
      "@/*": ["src/*"],
      "semantic-ui-css": ["node_modules/fomantic-ui-css"],
      "mobx-react": ["node_modules/mobx-react-lite"],
      "lodash": ["node_modules/lodash-es"],
      "markdown-it": ["node_modules/@esm-bundle/markdown-it"]
    }
// ...

How do you apply this exactly?

wvhulle avatar Feb 06 '23 15:02 wvhulle

While I'd like to see first-class support for this as well, unfortunately tsconfig paths and resolve.alias are not a one-to-one behaviour.

  • tsconfig paths are a lot more lenient and involves multiple resolves / filesystem access to match the resolved path
  • resolve.alias is stricter where the first regex match will immediately replace and return the resolved path (only string manipulation)

Because of that it's not great to support this ootb and potentially slowing down more projects. vite-tsconfig-paths would still be the recommended way if you prefer the define-once experience. In the last meeting, we're open to documenting this as well.

bluwy avatar Jul 14 '23 07:07 bluwy