Skip to content

chore(core): build nx to local dist and use nodenext#34111

Merged
FrozenPandaz merged 71 commits intomasterfrom
chore/nx-local-dist
Mar 20, 2026
Merged

chore(core): build nx to local dist and use nodenext#34111
FrozenPandaz merged 71 commits intomasterfrom
chore/nx-local-dist

Conversation

@Coly010
Copy link
Copy Markdown
Contributor

@Coly010 Coly010 commented Jan 15, 2026

Current Behavior

The nx package compiles its TypeScript output to ../../dist/packages/nx/ (relative to the package root), which places build artifacts outside the package directory at the repo root level (dist/packages/nx/). This makes the package structure harder to reason about, complicates the build pipeline, and doesn't align with how most packages organize their output.

The package uses "module": "commonjs" with basic module resolution, which limits future migration paths toward ESM.

Expected Behavior

The nx package now builds to a local dist/ directory within the package itself (packages/nx/dist/). This is a cleaner, more standard layout — like having your tools in your own toolbox instead of scattered across the workshop.

Key changes:

Build configuration (packages/nx/tsconfig.lib.json):

  • outDir changed from ../../dist/packages/nx to dist (local to package)
  • module changed to nodenext with moduleResolution: nodenext
  • Updated include patterns to explicitly list source directories

Package entry points (packages/nx/package.json):

  • bin paths updated: ./bin/nx.js./dist/bin/nx.js
  • Added "type": "commonjs" explicitly
  • Added comprehensive exports map with @nx/nx-source condition for dev/test resolution back to TS source
  • Added postinstall path update to ./dist/bin/post-install

Module resolution fixes:

  • Created src/utils/handle-import.ts — a CJS-first import utility that falls back to ESM import() for ESM-only packages, providing a single migration point for future ESM work
  • Converted dynamic await import() calls to require(require.resolve()) pattern where needed to satisfy nodenext extension requirements
  • Plugin worker spawn path now uses correct .ts/.js extension based on runtime context (source vs compiled)

Test infrastructure:

  • Added custom jest-resolver.js for the nx package that resolves nx/... imports using the @nx/nx-source exports condition, so tests run against TS source
  • Updated jest.preset.js with SWC transformer configuration
  • Added chalk mock for test compatibility

CI and tooling:

  • Conformance check updated to build workspace-plugin first (the Nx Cloud runner lacks @swc-node/register for TS resolution)
  • Conformance rule paths in nx.json now point to compiled dist/workspace-plugin/src/... output
  • Added dist to eslint ignore patterns to prevent linting compiled output
  • Added workspace-plugin build target and updated its dependencies

Other fixes:

  • Various import path fixes across create-nx-workspace, gradle, and other packages to work with nodenext resolution
  • Updated e2e test paths to reference the new dist location
  • Fixed .gitignore and .npmignore for the new output structure

Related Issue(s)

Internal infrastructure improvement — no external issue.

@Coly010 Coly010 self-assigned this Jan 15, 2026
@vercel
Copy link
Copy Markdown

vercel bot commented Jan 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
nx-dev Ready Ready Preview Jan 23, 2026 5:18pm

Request Review

@netlify
Copy link
Copy Markdown

netlify bot commented Jan 15, 2026

Deploy Preview for nx-docs failed. Why did it fail? →

Name Link
🔨 Latest commit aa747a3
🔍 Latest deploy log https://app.netlify.com/projects/nx-docs/deploys/69bdba436b5600000847c534

@nx-cloud
Copy link
Copy Markdown
Contributor

nx-cloud bot commented Jan 15, 2026

View your CI Pipeline Execution ↗ for commit aa747a3

Command Status Duration Result
nx affected --targets=lint,test,build,e2e,e2e-c... ✅ Succeeded 10m 21s View ↗
nx run-many -t check-imports check-lock-files c... ✅ Succeeded 9s View ↗
nx-cloud record -- pnpm nx conformance:check ✅ Succeeded 7s View ↗
nx build workspace-plugin ✅ Succeeded 56s View ↗
nx-cloud record -- nx format:check ✅ Succeeded 12s View ↗
nx-cloud record -- nx sync:check ✅ Succeeded <1s View ↗
nx affected -t e2e-macos-local --parallel=1 --b... ✅ Succeeded 1m 1s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-20 21:37:49 UTC

nx-cloud[bot]

This comment was marked as outdated.

nx-cloud[bot]

This comment was marked as outdated.

@Coly010 Coly010 force-pushed the chore/nx-local-dist branch from e88f09d to 355cb3c Compare January 15, 2026 16:38
@Coly010 Coly010 changed the title chore(core): build nx to local dist and use nodenext" chore(core): build nx to local dist and use nodenext Jan 15, 2026
@Coly010 Coly010 force-pushed the chore/nx-local-dist branch from 0e73eba to 3038774 Compare January 15, 2026 17:55
@Coly010 Coly010 force-pushed the chore/nx-local-dist branch from 3038774 to bce8591 Compare January 15, 2026 18:03
nx-cloud[bot]

This comment was marked as outdated.

@Coly010 Coly010 force-pushed the chore/nx-local-dist branch from bce8591 to 4b4f86a Compare January 21, 2026 13:53
nx-cloud[bot]

This comment was marked as outdated.

nx-cloud[bot]

This comment was marked as outdated.

Coly010 and others added 17 commits March 20, 2026 12:13
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
…esbuild import

The react-native vite config template imported esbuild directly, which fails
during project graph processing in pnpm strict mode because esbuild is only
a transitive dependency of vite and not hoisted to root node_modules.

Fixes e2e-detox:e2e-macos-local failure.
When Nx is built to a local dist directory, resolveNx(null) computes
the "global root" by going 4 directories up from __dirname, which
lands in the wrong location and resolves to a different nx. This
causes isLocalInstall to be false, so the bin tries to require itself
(cached no-op) and nothing happens.

Adding localNx === __filename as a fallback check: if the workspace
wants this exact file, we are the local install by definition.
With nodenext module resolution, Node requires explicit file extensions
when resolving module paths. The daemon server spawn already uses
start.js with the extension, but the plugin worker path was missing it.
The conformance runner can't resolve TS conformance rules without
@swc-node/register. Build workspace-plugin to JS first, then point
conformance rule paths to the compiled dist output.
Add dist/ to eslint ignore patterns since the new outDir puts compiled
output inside packages/nx/dist/. Also add module boundary eslint-disable
for jest-resolver.js which needs a relative import.
When running from TS source (tests), use plugin-worker.ts. When running
from compiled dist (production), use plugin-worker.js.
Copy link
Copy Markdown
Contributor

@nx-cloud nx-cloud bot left a comment

Choose a reason for hiding this comment

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

Nx Cloud is proposing a fix for your failed CI:

We updated tools/workspace-plugin/package.json to fix the @nx/dependency-checks lint errors introduced when conformance rules were added to the workspace plugin. The missing packages (@nx/conformance, glob, js-yaml, shiki, semver) are now declared as dependencies, and the unused @nx/eslint entry has been removed. This aligns the declared dependencies with what is actually imported in the conformance rule source files.

Note

We are verifying this fix by re-running workspace-plugin:lint.

diff --git a/tools/workspace-plugin/package.json b/tools/workspace-plugin/package.json
index a9f9ef81bf..2fd35f48ba 100644
--- a/tools/workspace-plugin/package.json
+++ b/tools/workspace-plugin/package.json
@@ -5,12 +5,16 @@
   "generators": "./generators.json",
   "executors": "./executors.json",
   "dependencies": {
+    "@nx/conformance": "4.0.0",
     "@nx/devkit": "workspace:*",
-    "@nx/eslint": "workspace:*",
     "@nx/plugin": "workspace:*",
     "@nx/js": "workspace:*",
     "@xmldom/xmldom": "^0.8.10",
+    "glob": "7.1.4",
+    "js-yaml": "^4.1.0",
     "nx": "workspace:*",
+    "semver": "catalog:",
+    "shiki": "^4.0.2",
     "tslib": "catalog:typescript"
   },
   "type": "commonjs",

🔔 Heads up, your workspace has pending recommendations ↗ to auto-apply fixes for similar failures.

Apply fix via Nx Cloud  Reject fix via Nx Cloud


Or Apply changes locally with:

npx nx-cloud apply-locally lXvn-PtJK

Apply fix locally with your editor ↗   View interactive diff ↗



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

Copy link
Copy Markdown
Contributor

@nx-cloud nx-cloud bot left a comment

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 is proposing a fix for your failed CI:

We updated tools/workspace-plugin/package.json to fix the @nx/dependency-checks lint errors introduced when conformance rules were added to the workspace plugin. The missing packages (@nx/conformance, glob, js-yaml, shiki, semver) are now declared as dependencies, and the unused @nx/eslint entry has been removed. This aligns the declared dependencies with what is actually imported in the conformance rule source files.

Tip

We verified this fix by re-running workspace-plugin:lint.

diff --git a/tools/workspace-plugin/package.json b/tools/workspace-plugin/package.json
index a9f9ef81bf..2fd35f48ba 100644
--- a/tools/workspace-plugin/package.json
+++ b/tools/workspace-plugin/package.json
@@ -5,12 +5,16 @@
   "generators": "./generators.json",
   "executors": "./executors.json",
   "dependencies": {
+    "@nx/conformance": "4.0.0",
     "@nx/devkit": "workspace:*",
-    "@nx/eslint": "workspace:*",
     "@nx/plugin": "workspace:*",
     "@nx/js": "workspace:*",
     "@xmldom/xmldom": "^0.8.10",
+    "glob": "7.1.4",
+    "js-yaml": "^4.1.0",
     "nx": "workspace:*",
+    "semver": "catalog:",
+    "shiki": "^4.0.2",
     "tslib": "catalog:typescript"
   },
   "type": "commonjs",

🔔 Heads up, your workspace has pending recommendations ↗ to auto-apply fixes for similar failures.

Apply fix via Nx Cloud  Reject fix via Nx Cloud


Or Apply changes locally with:

npx nx-cloud apply-locally lXvn-PtJK

Apply fix locally with your editor ↗   View interactive diff ↗



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

Add missing dependencies (conformance, glob, js-yaml, semver, shiki)
and remove unused @nx/eslint.
Copy link
Copy Markdown
Contributor

@nx-cloud nx-cloud bot left a comment

Choose a reason for hiding this comment

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

Nx Cloud is proposing a fix for your failed CI:

We ran nx sync to remove the stale project reference to packages/eslint/tsconfig.lib.json from tools/workspace-plugin/tsconfig.lib.json. This reference became stale as a result of the workspace-plugin dependency changes introduced in this PR. Running nx sync keeps TypeScript project references consistent with the actual project dependency graph.

Note

We are verifying this fix by re-running nx-cloud record -- nx sync:check.

diff --git a/tools/workspace-plugin/tsconfig.lib.json b/tools/workspace-plugin/tsconfig.lib.json
index 19a65594..c6ce8fb2 100644
--- a/tools/workspace-plugin/tsconfig.lib.json
+++ b/tools/workspace-plugin/tsconfig.lib.json
@@ -26,9 +26,6 @@
     {
       "path": "../../packages/plugin/tsconfig.lib.json"
     },
-    {
-      "path": "../../packages/eslint/tsconfig.lib.json"
-    },
     {
       "path": "../../packages/devkit/tsconfig.lib.json"
     }

🔔 Heads up, your workspace has pending recommendations ↗ to auto-apply fixes for similar failures.

Apply fix via Nx Cloud  Reject fix via Nx Cloud


Or Apply changes locally with:

npx nx-cloud apply-locally L6fs-qRIq

Apply fix locally with your editor ↗   View interactive diff ↗



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

Copy link
Copy Markdown
Contributor

@nx-cloud nx-cloud bot left a comment

Choose a reason for hiding this comment

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

Nx Cloud is proposing a fix for your failed CI:

We ran nx sync to remove the stale project reference to packages/eslint/tsconfig.lib.json from tools/workspace-plugin/tsconfig.lib.json. This reference became stale as a result of the workspace-plugin dependency changes introduced in this PR. Running nx sync keeps TypeScript project references consistent with the actual project dependency graph.

Tip

We verified this fix by re-running nx-cloud record -- nx sync:check.

diff --git a/tools/workspace-plugin/tsconfig.lib.json b/tools/workspace-plugin/tsconfig.lib.json
index 19a65594..c6ce8fb2 100644
--- a/tools/workspace-plugin/tsconfig.lib.json
+++ b/tools/workspace-plugin/tsconfig.lib.json
@@ -26,9 +26,6 @@
     {
       "path": "../../packages/plugin/tsconfig.lib.json"
     },
-    {
-      "path": "../../packages/eslint/tsconfig.lib.json"
-    },
     {
       "path": "../../packages/devkit/tsconfig.lib.json"
     }

🔔 Heads up, your workspace has pending recommendations ↗ to auto-apply fixes for similar failures.

Apply fix via Nx Cloud  Reject fix via Nx Cloud


Or Apply changes locally with:

npx nx-cloud apply-locally L6fs-qRIq

Apply fix locally with your editor ↗   View interactive diff ↗



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

Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
Copy link
Copy Markdown
Contributor

@nx-cloud nx-cloud bot left a comment

Choose a reason for hiding this comment

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

✅ The fix from Nx Cloud was applied automatically

We ran nx sync to remove the stale project reference to packages/eslint/tsconfig.lib.json from tools/workspace-plugin/tsconfig.lib.json. This reference became stale as a result of the workspace-plugin dependency changes introduced in this PR. Running nx sync keeps TypeScript project references consistent with the actual project dependency graph.

Tip

We verified this fix by re-running nx-cloud record -- nx sync:check.

Suggested Fix changes
diff --git a/tools/workspace-plugin/tsconfig.lib.json b/tools/workspace-plugin/tsconfig.lib.json
index 19a65594..c6ce8fb2 100644
--- a/tools/workspace-plugin/tsconfig.lib.json
+++ b/tools/workspace-plugin/tsconfig.lib.json
@@ -26,9 +26,6 @@
     {
       "path": "../../packages/plugin/tsconfig.lib.json"
     },
-    {
-      "path": "../../packages/eslint/tsconfig.lib.json"
-    },
     {
       "path": "../../packages/devkit/tsconfig.lib.json"
     }

🔔 Heads up, your workspace has pending recommendations ↗ to auto-apply fixes for similar failures.

Revert fix via Nx Cloud  

View interactive diff ↗

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

@github-actions
Copy link
Copy Markdown
Contributor

This pull request has already been merged/closed. If you experience issues related to these changes, please open a new issue referencing this pull request.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants