Skip to content

NX @nx/vite:build executor resolves outputPath outside workspace root #34769

@cursor

Description

@cursor

Problem Statement

The @nx/vite:build executor in @nx/vite (v21.6.9) miscalculates the outDir passed to Vite, causing build output to be written outside the workspace directory. This affects the edit-content-bridge project and potentially any Vite-based library nested more than one level deep.

Root cause (in node_modules/@nx/vite/src/executors/build/build.impl.js, line 29):

const outDir = joinPathFragments(offsetFromRoot(projectRoot), options.outputPath)
    ?? resolved?.build?.outDir;

For edit-content-bridge at libs/edit-content-bridge:

  • offsetFromRoot("libs/edit-content-bridge")"../../"
  • options.outputPath"dist/libs/edit-content-bridge"
  • Result: "../../dist/libs/edit-content-bridge" (relative path)

This relative path is passed to Vite via mergeConfig, overriding the correct absolute path already set in vite.config.ts. Vite then resolves this relative path against its root (the workspace root /path/to/core-web), producing:

/path/to/core-web/../../dist/libs/edit-content-bridge → /path/dist/libs/edit-content-bridge

This writes output two directories above the workspace. The vite.config.ts already handles path resolution correctly using resolve(__dirname, ...), but the executor override defeats it.

Steps to Reproduce

  1. Reset NX cache: cd core-web && npx nx reset && rm -rf dist .nx
  2. Build the affected project: npx nx build edit-content-bridge
  3. Observe the error:
(!) outDir /dist/libs/edit-content-bridge is not inside project root and will not be emptied.
EACCES: permission denied, mkdir '/dist'

The exact misplaced path depends on where the workspace is cloned. For a workspace at /home/user/code/core/core-web, output would land at /home/user/code/dist/libs/edit-content-bridge.

Expected Behavior

Build output should go to core-web/dist/libs/edit-content-bridge (inside the workspace).

Actual Behavior

Build output is directed to a path outside the workspace, calculated by walking up from the workspace root by the depth of the project folder. On CI or containerized environments where the ancestor directory is not writable, the build fails outright.

Acceptance Criteria

  • npx nx build edit-content-bridge (with empty NX cache) writes output to core-web/dist/libs/edit-content-bridge
  • No files are created outside the core-web/ workspace directory
  • Full Maven build (./mvnw install -DskipTests) succeeds with empty NX cache

dotCMS Version

Latest from main branch (NX 21.6.9, @nx/vite 21.6.9, Vite 7.2.7)

Severity

Medium - Some functionality impacted

The build succeeds once NX cache is populated (e.g. from a previous successful build). It only fails on cold-cache builds or CI environments. Workaround: create the misplaced target directory, or pre-populate NX cache.

Links

  • NX vite executor source: node_modules/@nx/vite/src/executors/build/build.impl.js line 29
  • Affected project config: core-web/libs/edit-content-bridge/project.json
  • Vite config (correct resolution): core-web/libs/edit-content-bridge/vite.config.ts
  • NA (no Freshdesk ticket)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    Status

    New

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions