Skip to content

fix(core): support ${configDir} in tsconfig path alias resolution#36037

Open
leosvelperez wants to merge 1 commit into
masterfrom
gh-35804
Open

fix(core): support ${configDir} in tsconfig path alias resolution#36037
leosvelperez wants to merge 1 commit into
masterfrom
gh-35804

Conversation

@leosvelperez

Copy link
Copy Markdown
Member

Current Behavior

TypeScript's ${configDir} template (TS 5.5+) lets a tsconfig paths alias point at the project currently being compiled, e.g.:

"paths": { "@/*": ["${configDir}/src/app/*"] }

Nx's project-graph resolver read these mappings verbatim and never substituted the template. The literal ${configDir}/... path matched no project, so resolution fell back to whatever project sits at the workspace root. With @nx/enforce-module-boundaries this surfaced as false Imports of apps are forbidden errors when an app imported its own files through a configDir alias. Switching the same import to a relative path made the error disappear.

Expected Behavior

A ${configDir} path alias resolves to the importing file's own project, matching how tsc resolves it, so importing a project's own sources through the alias no longer triggers module-boundary violations.

Related Issue(s)

Fixes #35804

Implementation Details

TargetProjectLocator (used by both the project graph and enforce-module-boundaries) now expands ${configDir} in matched paths values before resolving, mirroring TypeScript's commandLineParser behavior: the template is matched case-insensitively and only as a prefix, then resolved against the importing file's project root (the directory of the tsconfig used for compilation). Only values that start with ${configDir} change; all other aliases are untouched. Added a regression test in target-project-locator.spec.ts covering nested, deeply nested, and root-project importers.


View session information ↗

TypeScript's `${configDir}` template in a tsconfig `paths` alias resolves to the
directory of the project being compiled, so an alias like
`"@/*": ["${configDir}/src/app/*"]` points each project at its own sources.
The project-graph resolver read these mappings verbatim and never substituted
the template. The literal path matched no project and fell back to whatever
project sits at the workspace root, so `enforce-module-boundaries` reported
false "Imports of apps are forbidden" errors for an app importing its own files
through a configDir alias.

The resolver now expands `${configDir}` the same way `tsc` does: it matches the
template case-insensitively and only as a prefix, then resolves it against the
importing file's project root. A configDir alias now resolves back into the
source project.
@netlify

netlify Bot commented Jun 18, 2026

Copy link
Copy Markdown

Deploy Preview for nx-docs ready!

Name Link
🔨 Latest commit 6b447cb
🔍 Latest deploy log https://app.netlify.com/projects/nx-docs/deploys/6a33ad7c782a4b00084a6fa8
😎 Deploy Preview https://deploy-preview-36037--nx-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@netlify

netlify Bot commented Jun 18, 2026

Copy link
Copy Markdown

Deploy Preview for nx-dev ready!

Name Link
🔨 Latest commit 6b447cb
🔍 Latest deploy log https://app.netlify.com/projects/nx-dev/deploys/6a33ad7c7f1c2300083a735c
😎 Deploy Preview https://deploy-preview-36037--nx-dev.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@nx-cloud

nx-cloud Bot commented Jun 18, 2026

Copy link
Copy Markdown
Contributor

View your CI Pipeline Execution ↗ for commit 6b447cb

Command Status Duration Result
nx affected --targets=lint,test,build,e2e,e2e-c... ✅ Succeeded 6m 8s View ↗
nx run-many -t check-imports check-lock-files c... ✅ Succeeded 3s View ↗
nx-cloud record -- pnpm nx-cloud conformance:check ✅ Succeeded 1m 1s View ↗
nx build workspace-plugin ✅ Succeeded <1s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded 18s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 5s View ↗

☁️ Nx Cloud last updated this comment at 2026-06-18 10:51:22 UTC

@leosvelperez leosvelperez self-assigned this Jun 18, 2026

@nx-cloud nx-cloud Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Important

At least one additional CI pipeline execution has run since the conclusion below was written and it may no longer be applicable.

Nx Cloud has identified a possible root cause for your failed CI:

We reviewed the two failing tasks and found neither is caused by this PR's changes. The examples-angular-rspack-mf-host:build failure is an environment issue — is-ci is missing from the nx dist bundle, unrelated to the ${configDir} tsconfig path resolution fix. The e2e-release E2E failure is a known flaky timeout (~11% flakiness rate) that affects a different test step than what was seen in other branches.

No code changes were suggested for this issue.

Trigger a rerun:

Rerun CI

Nx Cloud View detailed reasoning on Nx Cloud ↗


🎓 Learn more about Self-Healing CI on nx.dev

@leosvelperez leosvelperez marked this pull request as ready for review June 18, 2026 10:53
@leosvelperez leosvelperez requested a review from a team as a code owner June 18, 2026 10:53
@leosvelperez leosvelperez requested a review from MaxKless June 18, 2026 10:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use of typescript's configDir in an alias incorrectly triggers enforce-module-boundaries lint rule

1 participant