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

Support for ${configDir} syntax #156

Closed
2LeoCode opened this issue Sep 5, 2024 · 6 comments
Closed

Support for ${configDir} syntax #156

2LeoCode opened this issue Sep 5, 2024 · 6 comments
Labels
help wanted Extra attention is needed

Comments

@2LeoCode
Copy link

2LeoCode commented Sep 5, 2024

Since typescript 5.5, it is possible to use the ${configDir} variable inside include/exclude clauses to reference the directory path where the current tsconfig is located, but unfortunately vite-tsconfig-paths does not support this feature yet, so path aliases are not set when using it.

Example

/* tsconfig.base.json */
{
  "include": ["${configDir}/src"],
  "exclude": ["${configDir}/dist", "${configDir}/node_modules"],
}
/* tsconfig.json */
{
  "files": [],
  "references": [
    {
      "path": "./tsconfig.app.json"
    },
    {
      "path": "./tsconfig.vite.json"
    }
  ]
}
/* tsconfig.app.json */
{
  "extends": "./tsconfig.base.json",
  "compilerOptions": {
    "paths": {
      "@components/*": [
        "./src/components/*"
      ],
      /* ... */
    }
  },
  "include": [
    "src"
  ]
}

If I remove the "include": ["src"] at the end of tsconfig.app.json, the path aliases stop working in vite, but it shouldn't since ${configDir)/src expands to ./src

@gunters63
Copy link
Contributor

gunters63 commented Sep 13, 2024

I had the same problem in my monorepo and was forced to fall back to Vite resolve aliases:

Base tsconfig.json:

  "include": [
    "${configDir}/**/*",
     // include hidden files (Example: Remix .server directories or config files)
    "${configDir}/**/.*",
    "${configDir}/**/.*/**/*",
    "${configDir}/**/.*/**/.*"
  ],
...

Local tsconfig.json

  "extends": "@enso/tsconfig/tsconfig.json",
  "compilerOptions": {
    "paths": {
      "@/*": ["./src/*"]
    }
  }

Local vite.config.ts:

import { fileURLToPath, URL } from 'node:url';

export default defineConfig({
......
  resolve: {
    alias: [
      {
        find: '@',
        replacement: fileURLToPath(new URL('./src', import.meta.url)),
      },
    ],
  }
});

@caubut-charter
Copy link

caubut-charter commented Oct 10, 2024

Sharing my workaround for my use case. I am only using vitest for a back-end monorepo. I have several packages with multiple aliases (all declared globally in a base tsconfig). Discovered that order matters (e.g., @scope/package-a will match if it is before @scope/package-a/module-a) if trying to map over these aliases.

Not wanting to enforce a string order in my tsconfig, I resorted to just importing the tsconfig and clamping each alias with a regex.

This doesn't account for wildcards, so if you need those, additional work will be needed.

Also does not follow project references or support alias reuse (e.g., @ for current package).

import path from 'path';

import tsconfig from './tsconfig.base.json';

const alias = Object.entries(tsconfig.compilerOptions.paths).map(([module, modulePath]) => ({
  find: new RegExp(`^${module}$`),
  replacement: path.resolve(import.meta.dirname, modulePath[0]),
}));

edit: This could be a separate issue also. Been using bun test, but the coverage isn't meeting our needs, so recently have been working on getting vitest working. I just assumed it was due to $configDirs at first.

@ethanjdiamond
Copy link

+1 - I ran into this as well

@aleclarson aleclarson added the help wanted Extra attention is needed label Nov 4, 2024
@aleclarson
Copy link
Owner

aleclarson commented Nov 4, 2024

This was added upstream in dominikg/tsconfck#172. Try refreshing your lockfile and let me know if it works already. If it doesn't work, find tsconfck in your lockfile and check if its version is at least 3.1.0.

@sloonz
Copy link

sloonz commented Nov 8, 2024

Same issue. Installed version of tsconfck is 3.1.4. Tracked the issue, here is my findings :

Setup

/home/[redacted]/workspace/tsconfig.base.json (excerpt) :

  "include": ["${configDir}/app", "${configDir}/gen"],
  "compilerOptions": {
    "paths": {
      "~/*": ["${configDir}/app/*"],
      "~gen/*": ["${configDir}/gen/*"]
    }
  }

/home/[redacted]/workspace/apps/accounts/tsconfig.json :

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

/home/[redacted]/workspace/apps/accounts/app/routes/_auth.tsx includes ~/gen/types (which resolves to /home/[redacted]/workspace/apps/accounts/gen/types/index.ts). Note that tsc has no issue with the setup, the error arises when building with vite.

The issue

The isIncludedRelative test fails (https://github.com/aleclarson/vite-tsconfig-paths/blob/master/src/index.ts#L320) :

if(id === "~gen/types") console.log({id, project: project.tsconfigFile, baseUrl, paths, configDir, importerFile, relativeImporterFile, included: isIncludedRelative(relativeImporterFile), include: config.includ, include: config.include});
{
  id: '~gen/types',
  project: '/home/[redacted]/workspace/apps/accounts/tsconfig.json',
  baseUrl: undefined,
  paths: {
    '~/*': [ '/home/[redacted]/workspace/apps/accounts/app/*' ],
    '~gen/*': [ '/home/[redacted]/workspace/apps/accounts/gen/*' ]
  },
  configDir: '/home/[redacted]/workspace/apps/accounts',
  importerFile: '/home/[redacted]/workspace/apps/accounts/app/routes/_auth.tsx',
  relativeImporterFile: 'app/routes/_auth.tsx',
  included: false,
  include: [
    '/home/[redacted]/workspace/apps/accounts/app',
    '/home/[redacted]/workspace/apps/accounts/gen'
  ]
}

The issue is that the globs are absolute, not relative :

if(path2 === "./app/routes/_auth.tsx") console.log({path2, includers});
{
  path2: './app/routes/_auth.tsx',
  includers: [
    /^\.\/?\/home\/[redacted]\/workspace\/apps\/accounts\/app\/((?:[^/]*(?:\/|$))*)$/,
    /^\.\/?\/home\/[redacted]\/workspace\/apps\/accounts\/gen\/((?:[^/]*(?:\/|$))*)$/
  ]
}

The fix

Replacing

    const isIncludedRelative = getIncluder(
      config.include,
      config.exclude,
      outDir
    )

with

    const isIncludedRelative = getIncluder(
      config.include.map(path => relative(configDir, path)),
      config.exclude.map(path => relative(configDir, path)),
      outDir
    )

Fixed the issue for me.

@aleclarson
Copy link
Owner

Great sleuthing, @sloonz! 👏

Fixed in v5.1.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

6 participants