[workspace-plugin] library generator emits "^undefined" peer versions — reads rootPkg.dependencies but framework deps live in devDependencies since E0 #742

Open
opened 2026-07-20 18:31:51 +00:00 by spikerj · 2 comments
Owner

Found while scaffolding platform-activity-tracking-api (#740). The E2a library generator (tools/workspace-plugin/src/generators/library/generator.ts:37-39) reads:

const angularVersion: string = rootPkg.dependencies["@angular/core"];
const rxjsVersion: string = rootPkg.dependencies["rxjs"];
const tslibVersion: string = rootPkg.dependencies["tslib"];

But since the E0 housekeeping (SSR strip, epic #722), @angular/core and rxjs live in root devDependencies — only tslib is still in dependencies. Generated package.json comes out as:

"peerDependencies": { "@angular/common": "^undefined", "@angular/core": "^undefined", "rxjs": "^undefined" },
"dependencies": { "tslib": "^^2.8.1" }

Two bugs: (1) look in dependencies then fall back to devDependencies; (2) tslibDep: ^${tslibVersion}`` double-prefixes because the manifest value already carries ^ — strip/normalize before prefixing.

Low stakes (these per-lib manifests are informational under ng-packagr-lite), but every future nx g @spikersoft/workspace-plugin:library output is malformed until fixed. The two libs generated in #740 were corrected by hand.

Found while scaffolding `platform-activity-tracking-api` (#740). The E2a library generator (`tools/workspace-plugin/src/generators/library/generator.ts:37-39`) reads: ```ts const angularVersion: string = rootPkg.dependencies["@angular/core"]; const rxjsVersion: string = rootPkg.dependencies["rxjs"]; const tslibVersion: string = rootPkg.dependencies["tslib"]; ``` But since the E0 housekeeping (SSR strip, epic #722), `@angular/core` and `rxjs` live in root **devDependencies** — only `tslib` is still in `dependencies`. Generated package.json comes out as: ```json "peerDependencies": { "@angular/common": "^undefined", "@angular/core": "^undefined", "rxjs": "^undefined" }, "dependencies": { "tslib": "^^2.8.1" } ``` Two bugs: (1) look in `dependencies` then fall back to `devDependencies`; (2) `tslibDep: `^${tslibVersion}`` double-prefixes because the manifest value already carries `^` — strip/normalize before prefixing. Low stakes (these per-lib manifests are informational under ng-packagr-lite), but every future `nx g @spikersoft/workspace-plugin:library` output is malformed until fixed. The two libs generated in #740 were corrected by hand.
Author
Owner

Board-sweep verification (2026-07-22): bug CONFIRMED still live, root-caused exactly. tools/workspace-plugin/src/generators/library/generator.ts reads rootPkg.dependencies['@angular/core'] and ['rxjs'], but in the root package.json BOTH live under devDependencies (verified) → undefined → '^undefined' peers; tslib happens to sit in dependencies, which is why only some ranges rot. One-line fix: coalesce both maps, e.g. const dep = (k) => rootPkg.dependencies?.[k] ?? rootPkg.devDependencies?.[k]; and fail loudly if still undefined. No fix commit exists for the plugin since its E2a introduction (3c12680e).

Board-sweep verification (2026-07-22): bug CONFIRMED still live, root-caused exactly. tools/workspace-plugin/src/generators/library/generator.ts reads rootPkg.dependencies['@angular/core'] and ['rxjs'], but in the root package.json BOTH live under devDependencies (verified) → undefined → '^undefined' peers; tslib happens to sit in dependencies, which is why only some ranges rot. One-line fix: coalesce both maps, e.g. const dep = (k) => rootPkg.dependencies?.[k] ?? rootPkg.devDependencies?.[k]; and fail loudly if still undefined. No fix commit exists for the plugin since its E2a introduction (3c12680e).
Author
Owner

Re-verified against origin/masterNOT DONE, and there's a second bug in the same three lines.

tools/workspace-plugin/src/generators/library/generator.ts still reads all three versions from dependencies only:

const angularVersion: string = rootPkg.dependencies["@angular/core"];
const rxjsVersion: string = rootPkg.dependencies["rxjs"];
const tslibVersion: string = rootPkg.dependencies["tslib"];

No devDependencies fallback, and no loud failure when the lookup returns undefined.

The root manifest confirms the mismatch is live: package.json:78 opens "devDependencies" containing @angular/core (:92) and rxjs (:147), while "dependencies" doesn't open until :163, with tslib at :245. So two of the three resolve to undefined and emit ^undefined.

Second bug, not in the ticket body: tslib — the one that does resolve — is declared as "^2.8.1", already carrying its caret. The template then emits tslibDep: `^${tslibVersion}`^^2.8.1. So all three peer entries are malformed, just in two different ways. Worth fixing together, since anyone touching the ^undefined lines will be looking straight at it.

git log for that file shows exactly one commit ever — 438c4ac9, the E2a introduction. No fix has been attempted.

Remaining: read from dependencies ?? devDependencies (or merge both), strip any leading caret before re-adding one, and fail loudly rather than emitting a literal ^undefined into a generated package.json. Given the memory that a lib's package.json name must exactly match its import alias or consumer builds crash, a generator that silently emits malformed peer ranges is worth making noisy.

Re-verified against `origin/master` — **NOT DONE, and there's a second bug in the same three lines.** `tools/workspace-plugin/src/generators/library/generator.ts` still reads all three versions from `dependencies` only: ```ts const angularVersion: string = rootPkg.dependencies["@angular/core"]; const rxjsVersion: string = rootPkg.dependencies["rxjs"]; const tslibVersion: string = rootPkg.dependencies["tslib"]; ``` No `devDependencies` fallback, and no loud failure when the lookup returns `undefined`. The root manifest confirms the mismatch is live: `package.json:78` opens `"devDependencies"` containing `@angular/core` (`:92`) and `rxjs` (`:147`), while `"dependencies"` doesn't open until `:163`, with `tslib` at `:245`. So two of the three resolve to `undefined` and emit `^undefined`. **Second bug, not in the ticket body:** `tslib` — the one that *does* resolve — is declared as `"^2.8.1"`, already carrying its caret. The template then emits `` tslibDep: `^${tslibVersion}` `` → **`^^2.8.1`**. So all three peer entries are malformed, just in two different ways. Worth fixing together, since anyone touching the `^undefined` lines will be looking straight at it. `git log` for that file shows exactly **one** commit ever — `438c4ac9`, the E2a introduction. No fix has been attempted. **Remaining:** read from `dependencies ?? devDependencies` (or merge both), strip any leading caret before re-adding one, and fail loudly rather than emitting a literal `^undefined` into a generated `package.json`. Given the memory that a lib's `package.json` name must exactly match its import alias or consumer builds crash, a generator that silently emits malformed peer ranges is worth making noisy.
Sign in to join this conversation.