Known Issues And Solutions

Ecosistema completo para organización y gestión de contenido con interfaces espaciales

Known Issues & Solutions for NX Monorepo

Last Updated: January 19, 2025
Audience: Beginner to intermediate developers


Table of Contents

  1. Critical Issue: TypeScript 5.8.x + ng-packagr Incompatibility
  2. Issue: Files Generated in Source Directories
  3. Issue: "Cannot destructure property" Error
  4. Issue: Slow Builds and Hanging
  5. Emergency Recovery Procedures

Critical Issue: TypeScript 5.8.x + ng-packagr Incompatibility

Status: 🔴 PERMANENT WORKAROUND REQUIRED
Impact: HIGH - Blocks all Angular library builds
Discovered: October 2024


What's the Problem? (Plain English)

Short version: The tools we use to build Angular libraries are broken and incompatible with each other.

Long version:

We use three main tools:

  1. TypeScript 5.8.x - Compiles TypeScript to JavaScript
  2. Angular 20 - Our framework (requires TypeScript 5.8.x)
  3. ng-packagr - Tool that packages Angular libraries

The problem:

Result: You cannot build Angular libraries using the standard NX/Angular tools.


What Error Do You See?

When you try to build a library with the standard method:

yarn nx build my-library

You get:

TypeError: Cannot destructure property 'pos' of 'file.referencedFiles[index]' as it is undefined.
    at getReferencedFileLocation
    at fileIncludeReasonToDiagnostics

What this means: ng-packagr is trying to read a property that doesn't exist anymore in TypeScript 5.8.x.


Why Can't We Just Update Everything?

Good question! Here's why we're stuck:

Option 1: Update ng-packagr to version 21.x?

Option 2: Downgrade TypeScript?

Option 3: Downgrade Angular?

We're stuck between incompatible versions!


The Solution: Custom Build Script

Instead of using ng-packagr, we use our own custom build script.

File: tools/scripts/build-scripts/build-angular-library.js

What it does:

  1. Compiles TypeScript directly (bypasses ng-packagr)
  2. Generates Angular metadata
  3. Compiles SCSS to CSS
  4. Copies HTML templates and assets
  5. Outputs everything to dist/ only

Benefits:


How to Use the Custom Build Script

For New Libraries

When you create a new library:

# 1. Generate the library (standard way)
yarn nx generate @nx/angular:library my-new-library

# 2. Update project.json to use custom builder

Edit: libs/my-new-library/project.json

Replace this:

{
  "targets": {
    "build": {
      "executor": "@nx/angular:ng-packagr-lite",  // ← OLD (broken)
      "options": {
        "project": "libs/my-new-library/ng-package.json"
      }
    }
  }
}

With this:

{
  "targets": {
    "build": {
      "executor": "nx:run-commands",              // ← NEW (works!)
      "outputs": ["{workspaceRoot}/dist/libs/my-new-library"],
      "options": {
        "command": "node tools/scripts/build-scripts/build-angular-library.js my-new-library"
      },
      "configurations": {
        "production": {
          "command": "node tools/scripts/build-scripts/build-angular-library.js my-new-library"
        },
        "development": {
          "command": "node tools/scripts/build-scripts/build-angular-library.js my-new-library"
        }
      },
      "defaultConfiguration": "production",
      "cache": true
    }
  }
}

Key points:


For Existing Libraries

If you have an existing library that's broken:

Step 1: Check if it's using the old executor

cat libs/YOUR-LIBRARY/project.json | grep "executor"

If you see "@nx/angular:ng-packagr-lite", it's using the old (broken) method.

Step 2: Update project.json as shown above

Step 3: Update tsconfig.lib.json

Make sure your tsconfig.lib.json has:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "../../dist/libs/YOUR-LIBRARY",  // ← Output goes here
    "rootDir": "./src",                        // ← OR use rootDirs
    "composite": false,                        // ← MUST be false
    "declaration": true,
    "declarationMap": false,
    "sourceMap": false,
    "types": ["node"]
  },
  "exclude": [
    "src/**/*.spec.ts",
    "src/test-setup.ts",
    "jest.config.ts",
    "src/**/*.test.ts"
  ],
  "include": ["src/**/*.ts"]
}

Step 4: Clean and rebuild

# Remove old build artifacts
rm -rf dist/libs/YOUR-LIBRARY

# Build with custom script
yarn nx build YOUR-LIBRARY --skip-nx-cache

Which Libraries Are Already Fixed?

All 18 Angular libraries in our monorepo use the custom builder:

Root Level (15):

Nested in theme-system (3):

Plain TypeScript (not Angular-specific):


Issue: Files Generated in Source Directories

Status: 🟢 SOLVED (with custom builder)
Impact: MEDIUM - Pollutes source code, confuses Git


What's the Problem?

After building, you find .js, .d.ts, and .js.map files inside your source directories:

libs/my-library/src/
  ├── index.ts
  ├── index.js          ← Shouldn't be here!
  ├── index.d.ts        ← Shouldn't be here!
  ├── index.js.map      ← Shouldn't be here!
  └── lib/
      ├── component.ts
      ├── component.js  ← Shouldn't be here!
      └── component.d.ts ← Shouldn't be here!

Why this is bad:


What Should Happen

ALL build output should go to dist/:

libs/my-library/src/
  ├── index.ts          ← Source files (only these!)
  └── lib/
      └── component.ts

dist/libs/my-library/
  ├── index.js          ← Build output (goes here!)
  ├── index.d.ts
  ├── index.js.map
  └── lib/
      ├── component.js
      ├── component.d.ts
      └── component.js.map

Rule: If you see .js or .d.ts files in libs/, something is wrong!


Why Does This Happen?

Common causes:

Cause 1: Wrong outDir in tsconfig

Your tsconfig.lib.json might have:

{
  "compilerOptions": {
    "outDir": "./dist"  // ← WRONG! This is relative to the library folder
  }
}

This creates:

libs/my-library/dist/  ← Wrong place!

Fix: Use absolute path from workspace root:

{
  "compilerOptions": {
    "outDir": "../../dist/libs/my-library"  // ← CORRECT!
  }
}

Cause 2: composite: true

If your tsconfig.lib.json has:

{
  "compilerOptions": {
    "composite": true  // ← This can cause source pollution
  }
}

TypeScript's "project references" feature can output files in strange places.

Fix: Set to false:

{
  "compilerOptions": {
    "composite": false  // ← Safe!
  }
}

Cause 3: Missing rootDir

Without rootDir, TypeScript might output files in the wrong structure.

Fix: Always set rootDir:

{
  "compilerOptions": {
    "rootDir": "./src",  // ← Forces proper structure
    "outDir": "../../dist/libs/my-library"
  }
}

How to Clean Up Source Pollution

If you already have generated files in your source directories:

Option 1: Automated cleanup script

node tools/scripts/cleanup-all-source-pollution.js

This script:

Option 2: Manual cleanup

# Find all generated files in source
find libs/ -name "*.js" -o -name "*.d.ts" -o -name "*.js.map"

# Remove them (BE CAREFUL!)
find libs/ -name "*.js" -o -name "*.d.ts" -o -name "*.js.map" | xargs rm -f

⚠️ Warning: The manual method removes ALL .js files, including config files. Use the automated script instead!


How to Prevent Source Pollution

Use our custom build script!

The custom builder at tools/scripts/build-scripts/build-angular-library.js:

If you're using the custom builder and still seeing source pollution, that's a bug - report it!


Issue: "Cannot destructure property" Error

Full error message:

TypeError: Cannot destructure property 'pos' of 'file.referencedFiles[index]' as it is undefined.
    at getReferencedFileLocation (/node_modules/ng-packagr/lib/ts/cache-compiler-host.js:245:58)
    at fileIncludeReasonToDiagnostics (/node_modules/typescript/lib/typescript.js:140819:57)

What's happening:

This is the main symptom of the TypeScript 5.8.x + ng-packagr incompatibility described above.

Quick check:

# Check your TypeScript version
npx tsc --version
# Should show: Version 5.8.x

# Check if library uses ng-packagr
cat libs/YOUR-LIBRARY/project.json | grep "ng-packagr"
# If you see "ng-packagr-lite", that's the problem!

Solution:

Switch to the custom build script (see solution above).


Issue: Slow Builds and Hanging

Symptoms:


Common Causes & Fixes

Cause 1: TypeScript Getting Stuck on Type Errors

What's happening: TypeScript is trying to resolve type errors and getting stuck in loops.

How to test:

# Try building with verbose output
yarn nx build YOUR-LIBRARY --verbose

# If it hangs at "Compiling TypeScript...", that's the issue

Fix 1: Add skipLibCheck

Edit tsconfig.lib.json:

{
  "compilerOptions": {
    "skipLibCheck": true  // ← Skip checking .d.ts files
  }
}

This makes TypeScript skip type-checking library .d.ts files, which is much faster.

Fix 2: Check for circular dependencies

# Use madge to detect circular dependencies
npx madge --circular libs/YOUR-LIBRARY/src

If you see circular dependencies, refactor your code to break the cycle.


Cause 2: Too Many Files in rootDirs

What's happening: Your tsconfig.lib.json has too many entries in rootDirs:

{
  "rootDirs": [
    "./src",
    "../storage-system/src",
    "../theme-system/src",
    "../ux-icons/src",
    "../ux-menu/src",
    "../ux-panel/src",
    // ... 10 more libraries
  ]
}

TypeScript has to check ALL of these directories on every compile.

Fix: Only include libraries you actively develop:

{
  "rootDirs": [
    "./src",
    "../storage-system/src"  // ← Only the essential ones
  ],
  "paths": {
    // Use dist/ for others
    "@ux-icons": ["../../dist/libs/ux-icons/index"]
  }
}

Cause 3: NX Cache Issues

What's happening: NX's cache is corrupted or stale.

Fix:

# Clear NX cache
yarn nx reset

# Clear all caches
rm -rf dist/ .angular/ node_modules/.cache

# Try building again
yarn nx build YOUR-LIBRARY --skip-nx-cache

Cause 4: Too Many Processes Running

What's happening: Your system is running out of resources.

Check:

# Check running node processes
ps aux | grep node | wc -l

# Check TypeScript servers
ps aux | grep tsserver

Fix:

# Kill all TypeScript servers
killall -9 tsserver node

# Or kill specific processes
pkill -f 'typescript-language-features'

# Then retry
yarn nx build YOUR-LIBRARY

Emergency Recovery Procedures

When Everything is Broken

Follow these steps in order:


Step 1: Nuclear Clean

# 1. Close your IDE completely (Cmd+Q)

# 2. Kill all Node processes
killall -9 node tsserver

# 3. Clear all caches and build artifacts
rm -rf dist/ .angular/ .nx/ node_modules/.cache

# 4. Clean source directories
node tools/scripts/cleanup-all-source-pollution.js

# 5. Reset NX
yarn nx reset

Step 2: Verify Configuration

Check: libs/YOUR-LIBRARY/project.json

Should use custom build script:

{
  "targets": {
    "build": {
      "executor": "nx:run-commands",
      "options": {
        "command": "node tools/scripts/build-scripts/build-angular-library.js YOUR-LIBRARY"
      }
    }
  }
}

Check: libs/YOUR-LIBRARY/tsconfig.lib.json

Should have proper paths:

{
  "compilerOptions": {
    "outDir": "../../dist/libs/YOUR-LIBRARY",
    "rootDir": "./src",  // OR rootDirs
    "composite": false
  }
}

Step 3: Rebuild Dependencies First

# Build storage-system first (most libraries depend on it)
yarn nx build storage-system --skip-nx-cache

# Then build your library
yarn nx build YOUR-LIBRARY --skip-nx-cache

Step 4: Test Build

# Build should succeed
yarn nx build YOUR-LIBRARY

# Verify output exists
ls -la dist/libs/YOUR-LIBRARY/

# Verify NO source pollution
find libs/YOUR-LIBRARY/src -name "*.js" -o -name "*.d.ts"
# Should return NOTHING (or only intentional config files)

Step 5: Restart IDE

# Reopen your IDE
# Then restart TypeScript server:
# Cmd+Shift+P → "TypeScript: Restart TS Server"

If Build Still Fails

Get diagnostic information:

# 1. Build with verbose output
yarn nx build YOUR-LIBRARY --verbose --skip-nx-cache 2>&1 | tee build-log.txt

# 2. Check TypeScript directly
cd libs/YOUR-LIBRARY
npx tsc --project tsconfig.lib.json --noEmit

# 3. Check for syntax errors
npx eslint src/

Check the build log for:


Debugging Checklist

When something goes wrong, go through this checklist:

✅ Build Configuration

✅ TypeScript Configuration

✅ Path Mappings

✅ Source Directories

✅ Dependencies

✅ System State


Quick Reference Commands

# Clean everything
yarn nx reset && rm -rf dist/ .angular/ node_modules/.cache

# Clean source directories
node tools/scripts/cleanup-all-source-pollution.js

# Build single library (skip cache)
yarn nx build YOUR-LIBRARY --skip-nx-cache

# Build with dependencies
yarn nx build YOUR-LIBRARY --with-deps

# Check for source pollution
find libs/ -name "*.js" -o -name "*.d.ts" | grep -v node_modules | grep -v dist

# Kill stuck processes
killall -9 tsserver node

# Check TypeScript version
npx tsc --version

# Test TypeScript compilation directly
cd libs/YOUR-LIBRARY && npx tsc --project tsconfig.lib.json --noEmit

When Will This Be Fixed Upstream?

Short answer: Unknown. Could be months or years.

The situation:

Our approach:


History & Changes

Date Change Impact
2024-10-17 Discovered TypeScript 5.8.x + ng-packagr bug All Angular builds broken
2024-10-17 Created custom build script Fixed all builds
2024-10-17 Migrated all 18 Angular libraries All libraries working
2024-10-17 Created cleanup script for source pollution Prevention-based solution
2025-01-19 Documented rootDirs pattern Improved developer experience
2025-01-19 Created beginner-friendly docs Better onboarding

Related Documentation


Remember: This is NOT a configuration mistake - it's a KNOWN BUG in the tooling. The custom build script is the correct and permanent solution. Don't waste time trying to make ng-packagr work with TypeScript 5.8.x!