#37091·nx

@nx/esbuild: --output-path CLI override is ignored for the bundled entry file (getOutfile uses context.target.options.outputPath instead of normalized options)

Author: VijaySunderCreated Sep 17, 2026Updated Sep 17, 2026
Labelstype: bug

Current Behavior

When running an @nx/esbuild:esbuild build for a "singleEntry + bundle" Node app and overriding the output directory via the --output-path CLI flag (or a target configuration that isn't the one baked into project.json), the bundled entry file (e.g. main.js) is written to the static outputPath configured in the project's project.json target — NOT to the overridden path.

Everything else in the same build (copied assets, generated package.json/lockfile via generatePackageJson) correctly respects the overridden --output-path. Only the actual JS bundle file ends up in the wrong directory.

This is a silent failure: the build exits 0, "Successfully ran target", and the override directory looks fully populated (assets, fixtures, package.json) — just missing the one file (main.js) that makes the output runnable. We only noticed because a Docker image built from the "overridden" output directory failed at runtime with Cannot find module './main.js'.

Root cause (traced in v23.2.1): node_modules/@nx/esbuild/dist/src/executors/esbuild/lib/build-esbuild-options.js, function getOutfile:

function getOutfile(format, options, context) {
    const ext = getOutExtension(format, options, context);
    const candidate = joinPathFragments(context.target.options.outputPath, options.outputFileName);
    ...
}

context.target.options.outputPath is the unmerged, static value from project.json for that target. It does not reflect a CLI --output-path override (or any override that isn't statically present in the target/configuration definition read from the project graph). Meanwhile copyAssets and copyPackageJson (called earlier in esbuild.impl.js) are passed the normalized options object, which does correctly include the override — hence the asset/package.json vs. bundle-file inconsistency.

Expected Behavior

When --output-path=<dir> (or any equivalent override) is passed on the CLI, ALL build outputs — including the bundled entry file computed via getOutfile — should be written to the overridden directory, consistent with where assets and the generated package.json are written.

At minimum, getOutfile should use the normalized options.outputPath (which reflects CLI/configuration overrides) instead of context.target.options.outputPath (the static project.json value).

GitHub Repo

No response

Steps to Reproduce

  1. In an Nx workspace, create/use a Node app project with an @nx/esbuild:esbuild build target configured roughly like:

    { "targets": { "build-container": { "executor": "@nx/esbuild:esbuild", "options": { "platform": "node", "outputPath": "dist-a", "format": ["cjs"], "main": "apps/my-app/src/main.ts", "tsConfig": "apps/my-app/tsconfig.app.json", "generatePackageJson": true } } } }

  2. Run the target with the default (static) outputPath and confirm dist-a/main.js is produced:

    npx nx build-container my-app --skip-nx-cache

  3. Clean both directories, then run the SAME target but override the output path via CLI:

    rm -rf dist-a dist-b npx nx build-container my-app --skip-nx-cache --output-path=dist-b

  4. Inspect the results:

    • dist-b/ contains assets and package.json (respects the override) but NOT main.js.
    • dist-a/main.js exists instead — the bundle silently landed in the static project.json path, not the overridden one.

Nx Report

bash
Node           : 24.20.0
OS             : win32-x64
Native Target  : x86_64-windows
npm            : 11.19.0
daemon         : Available

nx                : 23.2.1
@nx/js            : 23.2.1
@nx/eslint        : 23.2.1
@nx/workspace     : 23.2.1
@nx/angular       : 23.2.1
@nx/jest          : 23.2.1
@nx/devkit        : 23.2.1
@nx/esbuild       : 23.2.1
@nx/eslint-plugin : 23.2.1
@nx/node          : 23.2.1
@nx/vite          : 23.2.1
@nx/vitest        : 23.2.1
@nx/web           : 23.2.1
@nx/webpack       : 23.2.1
@nx/docker        : 23.2.1
typescript        : 6.0.3
---------------------------------------
Registered Plugins:
@nx/webpack/plugin
@nx/eslint/plugin
@nx/vite/plugin
@nx/vitest
@nx/jest/plugin

Failure Logs

bash

Package Manager Version

No response

Operating System

  • macOS
  • Linux
  • Windows
  • Other (Please specify)

Additional Information

No response