fix(js): resolve build output dir from globbed outputs in node executor#35288
fix(js): resolve build output dir from globbed outputs in node executor#35288FrozenPandaz merged 3 commits intomasterfrom
Conversation
✅ Deploy Preview for nx-dev ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for nx-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
|
View your CI Pipeline Execution ↗ for commit eb8cf9d
☁️ Nx Cloud last updated this comment at |
|
Hey @leosvelperez, thanks for this fix. I just wanted to confirm something, as you closed the issue I opened as duplicate of 35198, however, taking a closer look they seem to be different issues. My issue is only when the app imports a buildable lib. Running the nestjs api with The issue you mentioned is affected directly when running the app and not specifically when it imports a buildable lib. The stack traces also differ, mine is related to how imports are resolved and the one this PR fixes is related to how scripts to run are resolved. Just wanted to make sure that I understand this correctly, since I tested these changes locally and still see the same error. |
Using your function calculateResolveMappings(
context: ExecutorContext,
options: NodeExecutorOptions
): Record<string, string> {
const parsed = parseTargetString(options.buildTarget, context);
const { dependencies } = calculateProjectBuildableDependencies(/* … */);
return dependencies.reduce((m, c) => {
if (c.node.type !== 'npm' && c.outputs[0] != null) {
- m[c.name] = joinPathFragments(context.root, c.outputs[0]);
+ // Same treatment as getFileToRun above — `outputs[0]` may be a glob
+ // from the inferred `@nx/js/typescript` build target. Without stripping
+ // it, the runtime `require('@scope/my-lib')` is rewritten to the literal
+ // glob string via NX_MAPPINGS and Node throws MODULE_NOT_FOUND.
+ const outputDir = stripGlobToBaseDir(c.outputs[0]);
+ m[c.name] = joinPathFragments(context.root, outputDir);
}
return m;
}, {} as Record<string, string>);
} |
|
@gg-martins091 good catch! You're right. The issue is caused by the same underlying root cause but it requires an additional fix. I'll update this PR with the fix for what you reported. Thanks for the investigation! |
…ings [Self-Healing CI Rerun]
There was a problem hiding this comment.
Nx Cloud has identified a flaky task in your failed CI:
🔂 Since the failure was identified as flaky, we triggered a CI rerun by adding an empty commit to this branch.
🔔 Heads up, your workspace has pending recommendations ↗ to auto-apply fixes for similar failures.
🎓 Learn more about Self-Healing CI on nx.dev
…or (#35288) ## Current Behavior The `@nx/js:node` executor fails when combined with the inferred `@nx/js/typescript` build target — in two distinct ways: 1. **Script-to-run resolution**: fails with `Could not find <project>/dist/**/*.{js,cjs,mjs,jsx,d.ts,d.cts,d.mts}{,.map}/main.js. Make sure your build succeeded.` — the executor's `getFileToRun` was appending `main.js` onto the glob output pattern. 2. **Buildable-dep import resolution**: when the node app imports a buildable lib that also uses the inferred build target, `require('@scope/my-lib')` throws `MODULE_NOT_FOUND` because `calculateResolveMappings` passes the literal glob into `NX_MAPPINGS`, which the CJS require override / ESM loader then tries to resolve. Both regressed after #35041 narrowed the inferred build target's `outputs[0]` from `{projectRoot}/dist` to `{projectRoot}/dist/**/*.{js,...}{,.map}` (to prevent cross-OS cache pollution). ## Expected Behavior `outputs` entries are cache patterns and may legitimately contain globs. The node executor now strips the glob portion back to the last path separator before using the value as a directory, in both `getFileToRun` and `calculateResolveMappings`. Handles `**`, `*`, `?`, character classes, brace expansion, extglob, and Windows/POSIX separators. ## Related Issue(s) Fixes #35198 Fixes #35301 --------- Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
|
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. |
Current Behavior
The
@nx/js:nodeexecutor fails when combined with the inferred@nx/js/typescriptbuild target — in two distinct ways:Could not find <project>/dist/**/*.{js,cjs,mjs,jsx,d.ts,d.cts,d.mts}{,.map}/main.js. Make sure your build succeeded.— the executor'sgetFileToRunwas appendingmain.jsonto the glob output pattern.require('@scope/my-lib')throwsMODULE_NOT_FOUNDbecausecalculateResolveMappingspasses the literal glob intoNX_MAPPINGS, which the CJS require override / ESM loader then tries to resolve.Both regressed after #35041 narrowed the inferred build target's
outputs[0]from{projectRoot}/distto{projectRoot}/dist/**/*.{js,...}{,.map}(to prevent cross-OS cache pollution).Expected Behavior
outputsentries are cache patterns and may legitimately contain globs. The node executor now strips the glob portion back to the last path separator before using the value as a directory, in bothgetFileToRunandcalculateResolveMappings. Handles**,*,?, character classes, brace expansion, extglob, and Windows/POSIX separators.Related Issue(s)
Fixes #35198
Fixes #35301