dividab / tsconfig-paths

Load node modules according to tsconfig paths, in run-time or via API.
MIT License
1.82k stars 104 forks source link

Add support for relative paths from extended tsconfig #265

Open alSergey opened 8 months ago

alSergey commented 8 months ago

Hello, thanks for the cool library. I'm using nuxt and have encountered an issue where when using the library I'm getting incorrect relative paths returned from tsconfig.

Example

FIle System

tsconfig.json

{
  "extends": "./.nuxt/tsconfig.json"
}

.nuxt/tsconfig.json

{
  "compilerOptions": {
    "paths": {
      "~": [
        ".."
      ],
      "assets": [
        "../assets"
      ],
      "#app": [
        "../node_modules/nuxt/dist/app"
      ],
      "#imports": [
        "./imports"
      ],
    }
  },
}

Expected

{
  "paths": {
    "~": [
      "."
    ],
    "assets": [
      "assets"
    ],
    "#app": [
      "node_modules/nuxt/dist/app"
    ],
    "#imports": [
      ".nuxt/imports"
    ],
  }
}

Result

{
  "paths": {
    "~": [
      ".."
    ],
    "assets": [
      "../assets"
    ],
    "#app": [
      "../node_modules/nuxt/dist/app"
    ],
    "#imports": [
      "./imports"
    ],
  }
}

Suggestion

When searching for paths in tsconfig.json, consider the path to the tsconfig file in which the paths were found and the baseUrl field.

Example code

const filesBasePath = path.join(configRelativeDir, baseUrl || '.') // configRelativeDir = '.nuxt'

const relativePaths = Object.entries(paths).reduce((obj, [key, values]) => ({
      ...obj,
      [key]: values?.map((item) => path.join(filesBasePath, item)),
}), {})
xak2000 commented 1 week ago

A related commit, that fixed the same problem for compilerOptions.baseUrl: 2b54ffa1c47ac38d78265a23a73c3f6362b471ec.

The relevant part is https://github.com/dividab/tsconfig-paths/commit/2b54ffa1c47ac38d78265a23a73c3f6362b471ec#diff-4269c82cfe6700a0f2edfef2b8f8a348b4b8f7c06f40071b294a4a138d9e6d63R121-R131

and the comment is:

baseUrl should be interpreted as relative to the base tsconfig, but we need to update it so it is relative to the original tsconfig being loaded

I think the idea is the same. Each relative path in compilerOptions.paths should be modified to be relative to the original tsconfig being loaded. Without doing this, these paths do not have much sense after merging them together into a single array, as some of them are relative to the original tsconfig, while others are relative to tsconfig from extends property.