Skip to content

Regression (22.7.0): resolvePathsBaseUrl uses JSON.parse — breaks on tsconfig files with // comments (JSONC) #35537

@aqeelat

Description

@aqeelat

Current Behavior

After upgrading from Nx 22.6.5 to 22.7.1, all Angular buildable library builds fail with TS2307: Cannot find module'@workspace/lib-name' for workspace dependencies. The TypeScript path mappings are resolved relative to the project directory instead of the workspace root.

Expected Behavior

Buildable library builds should resolve workspace dependencies correctly, as they did in 22.6.5 and earlier.

Root Cause

PR #34965 introduced resolvePathsBaseUrl() in packages/js/src/utils/typescript/ts-config.ts. This function walks the tsconfig extends chain using JSON.parse(readFileSync(...)) to find where paths is defined and what baseUrl applies.

Problem: JSON.parse cannot handle // comments (JSONC), which are extremely common in tsconfig files. When parsing fails, the catch block silently skips the file, breaking the extends chain walk. The function never reaches tsconfig.base.json (where paths and baseUrl are defined), so it falls back to the project's own directory as the resolution base.

This produces incorrect path mappings like:

"@workspace/data-layer": ["{workspaceRoot}/libs/my-lib/dist/libs/data-layer"]

instead of:

"@workspace/data-layer": ["{workspaceRoot}/dist/libs/data-layer"]

Reproduction

Any Nx workspace with:

  1. Multiple buildable Angular libraries with cross-dependencies
  2. A shared intermediate tsconfig (e.g., libs/tsconfig.json) in the extends chain that contains a // comment

Example libs/tsconfig.json:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    // TODO: fix this later
    "strictPropertyInitialization": false
  }
}

Each lib's tsconfig.json extends "../tsconfig.json" → which extends "../tsconfig.json" (the shared one with the comment) → which extends "tsconfig.base.json" (where paths + baseUrl live).

The JSON.parse failure on the commented file breaks the chain, so resolvePathsBaseUrl returns the lib directory instead of the workspace root.

Suggested Fix

Use TypeScript's readConfigFile (which handles JSONC) instead of JSON.parse:

// packages/js/src/utils/typescript/ts-config.ts — resolvePathsBaseUrl()

// Before:
const raw = JSON.parse(readFileSync(absolute, 'utf-8'));

// After:
const ts = require('typescript');
const { config: raw } = ts.readConfigFile(absolute, ts.sys.readFile);

This is the same approach already used by the readTsConfig function in the same file. The same fix should be applied to the duplicated version in register.ts (mentioned in PR #34965).

Environment

  • Nx: 22.7.1
  • @nx/angular: 22.7.1
  • Angular: 21+
  • Node: 22.x

Workaround

Remove all // comments from tsconfig files in the extends chain between the project and the root tsconfig.base.json.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions