aleclarson / vite-tsconfig-paths

Support for TypeScript's path mapping in Vite
MIT License
1.28k stars 45 forks source link

Unable to resolve transitive path #12

Closed JakeGinnivan closed 3 years ago

JakeGinnivan commented 3 years ago

Maintainer note: See this comment for a solution.


Hey Alec,

I've just given this lib a spin and hit an issue in my mono repo where a mapped path tries to load another module in a mapped path and fails.

Here is the example:

/apps/frontend /libs/lib1 /libs/lib2

The libs have names/path mappings of @libs/lib1 and @libs/lib2 for instance.

Frontend loads lib1 fine, but lib1 tries to import lib2 and it can't resolve.

I've tracked the issue down to isLocalDescendant. My tsconfig is in /apps/frontend, but because the importer is @libs/lib1 it thinks that lib2 is not a local descendant and it fails to resolve.

Solutions?

I basically need to be able to specify the root as the repo base (ie cwd()), and the tsconfigRoot as two separate options.

Possible non-breaking change, add a baseDir option? Naming is hard, especially with the current value being called root.

Ideas?

aleclarson commented 3 years ago

Can you move paths and baseUrl to a new tsconfig.json in the repo base, and extend that tsconfig.json from the package-specific tsconfig.json files?

Then set root option to the repo base.

JakeGinnivan commented 3 years ago

Nope, my setup is to take advantage of TypeScript project references. My root tsconfig is the solution style config which just references all the other projects

aleclarson commented 3 years ago
JakeGinnivan commented 3 years ago

Sorry for the delay.

lib1

{
  "extends": "../../tsconfig.settings.json",
  "compilerOptions": {
    "outDir": "./dist",
    "rootDir": "./src",
    "types": [
      "jest",
      "node"
    ]
  },
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx"
  ],
  "references": [{ "path": "../lib2" }],
}

app

{
  "extends": "../../tsconfig.settings.json",
  "compilerOptions": {
    "outDir": "./dist",
    "rootDir": "./src",
    "types": [
      "jest",
      "node"
    ]
  },
  "references": [{ "path": "../../libs/lib1" }],
  "include": [
    "src/**/*.ts",
    "src/**/*.tsx"
  ]
}

settings

{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "declaration": true,
    "noEmit": false,
    "composite": true,
    "incremental": true
  },
  "exclude": [
    "node_modules",
    "tmp"
  ]
}

base

{
  "compileOnSave": false,
  "compilerOptions": {
    "rootDir": ".",
    "sourceMap": true,
    "declaration": false,
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "target": "es2015",
    "module": "esnext",
    "lib": ["es2017", "dom"],
    "skipLibCheck": true,
    "skipDefaultLibCheck": true,
    "baseUrl": ".",
    "paths": {
      "@proj/lib1": ["libs/lib1/src/index.ts"],
      "@proj/lib2": ["libs/lib2/src/index.ts"]
    }
  },
  "exclude": ["node_modules", "tmp"]
}
JakeGinnivan commented 3 years ago

And no, no symlinks needed.

aleclarson commented 3 years ago

Would you mind forking and updating the demo folder to match your setup? Then I'll see what I can do to support it OOTB. 👍

aleclarson commented 3 years ago

Can you upgrade to v3.2.1 and try the following setup?

// Assuming your vite.config.ts exists in ./app
tsconfigPaths({
  projects: ['..'],
})
jamosonic commented 3 years ago

I ran into this issue with an nx monorepo, which for all intents and purposes uses Typescript paths for library resolution.

I created a demo at https://github.com/jamos99/vite-tsconfig-paths-demo using 3.2.1. It seems that paths resolve just fine if both libraries are used directly, but fail if one of the libs is only transitively imported (e.g. my-lib2 imports my-lib1).

aleclarson commented 3 years ago

In v3.3.0, you should do the following:

tsconfigPaths({
  root: '../..',
})

I've tested with @jamos99's demo, and it works as expected. :)

jamosonic commented 3 years ago

Thanks heaps @aleclarson - that works 🥳

mycroes commented 2 years ago

I think documentation on the root property could be improved. Now when I'm reading the comment on root it makes sense, but I was about to file an issue when I spotted this one. Also, I'd think it would be possible to infer the typescript root project, which would remove the need for root in this situation at all.

aleclarson commented 2 years ago

I'd think it would be possible to infer the typescript root project, which would remove the need for root in this situation at all.

PR welcome :)

mwarnerdotme commented 2 years ago

In v3.3.0, you should do the following:

  • set the root option to point at the common ancestor shared by all projects whose tsconfig.json files you want this plugin to use
  • leave the projects option undefined
tsconfigPaths({
  root: '../..',
})

I've tested with @jamos99's demo, and it works as expected. :)

This solution seems to be broken in the latest version (3.4.1). When I use version 3.3.0 it works great! But if I just yarn add -W -D vite-tsconfig-paths this solution still results in transitive paths failing to resolve.

Is this solution outdated? I plan on using 3.3.0 until the latest version works with my nx monorepo.

aleclarson commented 2 years ago

@mwarnerdotme If you could fork this repo and create a branch with a failing setup in ./demo folder, I will take a look 👍

mwarnerdotme commented 2 years ago

Repo: https://github.com/mwarnerdotme/vite-tsconfig-paths-demo

Changing this to v3.3.0 and running yarn dev works!

But when it's set to v3.4.1 and you run yarn dev, it fails to resolve transitive paths.

aleclarson commented 2 years ago

@mwarnerdotme You're facing another issue, specifically a bug in tsconfig-paths (https://github.com/dividab/tsconfig-paths/issues/new)

Basically, the include in apps/my-app/tsconfig.app.json is being overwritten by the include in apps/my-app/tsconfig.json

jkhaui commented 2 years ago

@aleclarson you're my hero. I've lost count of how many hours/days/weeks I've lost pulling my hair out in an attempt to get TS path aliases/mapping working with vite.

Maximilianos commented 2 years ago

I had the same issue. I created a new Nx workspace and created an app with the @nxext/vite package, then a few libraries using @nrwl/js. Similar to the original post in this thread, the app depended on some libraries that then depended on other libraries within the workspace. When I tried to run the vite app by running nx serve my-vite-app it failed complaining that vite couldn't resolve the transitive dependencies.

In case anyone runs into this as well, to fix it I had to do all of the following (based on notes in this thread and elsewhere):

  1. add a tsconfig.json file to the root of the workspace (e.g. /tsconfig.json) extending the base tsconfig generated by Nx:
    {
    "extends": "./tsconfig.base.json",
    }
  2. add a vite.config.ts file to the vite app (e.g. /apps/my-vite-app/vite.config.ts) containing the following (note that it provides a root property for the vite-tsconfig-paths plugin pointing from the app's directory to the root of the workspace:
    
    import { defineConfig } from "vite"
    import tsconfigPaths from "vite-tsconfig-paths"

export default defineConfig({ plugins: [ tsconfigPaths({ root: "../..", }), ], build: { target: "esnext", }, })

3. update the vite app's `project.json` file (e.g `/apps/my-vite-app/project.json`) to use the newly created `vite.config.ts` file instead of the one provided by `@nxext/vite`:
```diff
{
  ...
  "targets": {
    "build": {
      ...
      "options": {
        ...
-       "configFile": "@nxext/vite/plugins/vite"
+       "configFile": "apps/my-vite-app/vite.config.ts"
      },
      ...
    },
    "serve": {
      ...
      "options": {
        ...
-       "configFile": "@nxext/vite/plugins/vite"
+       "configFile": "apps/my-vite-app/vite.config.ts"
      },
      ...
    },
    ...
  },
  ...
}

If I don't do any part of the above I get the transitive dependencies error described in the original post and elsewhere, so I understand all are required to hook vite up to how Nx organises the workspace.

Aaronius commented 2 years ago

Shouldn't this issue stay open, regardless of whether it's a bug in tsconfig-paths? I've spent about 7 hours trying to track this down and would love for this issue to have more visibility until tsconfig-paths gets fixed.

aleclarson commented 2 years ago

@Aaronius There is no bug in tsconfig-paths related to this issue. If you're referring to my comment here, that bug should be tracked in its own issue. Want to open one for it?

Aaronius commented 2 years ago

Okay, I misunderstood. I don't know if my issue is related, but I logged it here: https://github.com/aleclarson/vite-tsconfig-paths/issues/61