From 122a6326ca557fc7448e47c97a498e7c8d508b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leosvel=20P=C3=A9rez=20Espinosa?= Date: Tue, 14 Apr 2026 14:49:01 +0200 Subject: [PATCH 1/3] fix(js): resolve build output dir from globbed outputs in node executor --- packages/js/src/executors/node/node.impl.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/js/src/executors/node/node.impl.ts b/packages/js/src/executors/node/node.impl.ts index 9e05561409cf47..7f7792bf1f5491 100644 --- a/packages/js/src/executors/node/node.impl.ts +++ b/packages/js/src/executors/node/node.impl.ts @@ -453,7 +453,13 @@ function getFileToRun( projectRoot: project.data.root, workspaceRoot: context.root, }); - return path.join(outputFilePath, 'main.js'); + // `outputs` are cache patterns and may contain globs (e.g. the inferred + // `@nx/js/typescript` build target scopes its output to + // `{projectRoot}/dist/**/*.{js,...}` to avoid caching non-tsc files). + // Strip the glob portion back to the last path separator before it to + // recover the base output directory. + const outputDir = stripGlobToBaseDir(outputFilePath); + return path.join(outputDir, 'main.js'); } const fallbackFile = path.join('dist', project.data.root, 'main.js'); @@ -485,6 +491,16 @@ function getFileToRun( return join(context.root, buildOptions.outputPath, outputFileName); } +function stripGlobToBaseDir(pathWithGlob: string): string { + const globIdx = pathWithGlob.search(/[*?[{(]/); + if (globIdx === -1) { + return pathWithGlob.replace(/[\\/]+$/, ''); + } + const prefix = pathWithGlob.slice(0, globIdx); + const lastSep = Math.max(prefix.lastIndexOf('/'), prefix.lastIndexOf('\\')); + return lastSep === -1 ? '' : prefix.slice(0, lastSep); +} + function fileToRunCorrectPath(fileToRun: string): string { if (fileExists(fileToRun)) return fileToRun; From 56e4359b73dc9c93ca38ec0c0ea446cd1d1af203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Leosvel=20P=C3=A9rez=20Espinosa?= Date: Wed, 15 Apr 2026 17:15:17 +0200 Subject: [PATCH 2/3] fix(js): strip globs from buildable dep outputs in node executor mappings --- packages/js/src/executors/node/node.impl.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/js/src/executors/node/node.impl.ts b/packages/js/src/executors/node/node.impl.ts index 7f7792bf1f5491..48dcdd5253a08d 100644 --- a/packages/js/src/executors/node/node.impl.ts +++ b/packages/js/src/executors/node/node.impl.ts @@ -405,7 +405,11 @@ function calculateResolveMappings( ); return dependencies.reduce((m, c) => { if (c.node.type !== 'npm' && c.outputs[0] != null) { - m[c.name] = joinPathFragments(context.root, c.outputs[0]); + // `outputs` are cache patterns and may contain globs (e.g. from the + // inferred `@nx/js/typescript` build target). Strip the glob portion + // so the runtime require overrides resolve to the actual output dir. + const outputDir = stripGlobToBaseDir(c.outputs[0]); + m[c.name] = joinPathFragments(context.root, outputDir); } return m; }, {}); From eb8cf9de7d4c73625c708d55cc369ac60d40f33d Mon Sep 17 00:00:00 2001 From: "nx-cloud[bot]" <71083854+nx-cloud[bot]@users.noreply.github.com> Date: Thu, 16 Apr 2026 08:13:30 +0000 Subject: [PATCH 3/3] fix(js): strip globs from buildable dep outputs in node executor mappings [Self-Healing CI Rerun]