Nub 0.8.1
Nub 0.8.1 is a patch release: a lockfile fix for pnpm 12, a round of Node-version and loader compatibility fixes in the runtime, and global-install repairs in the package manager.
Note
pnpm 12 rejects a lockfile written by Nub 0.8.0 or earlier when a peer is declared optional: false (vitest declares vite that way). Nub wrote the entry as an empty mapping under peerDependenciesMeta; pnpm 12's reader fails on it with ERR_PNPM_BROKEN_LOCKFILE, where pnpm 10 accepted it. Nub now omits those entries, as pnpm does. (#814)
Package manager
| Area | What changed | PR |
|---|---|---|
| Lockfiles | peerDependenciesMeta records only optional: true entries, matching pnpm; pnpm 12 reads the result under --frozen-lockfile. |
#814 |
| Lockfiles | A lockfile read resolves against the declared package manager, not filename precedence. In a project declaring npm, a stray bun.lock no longer outranks package-lock.json and gets serialized back out as it. |
#781 |
| Global installs | nub install -g <pkg> produces a runnable command, and nub remove -g unlinks the bins it created instead of leaving dangling entries in the global bin directory. Fixes #642. |
#773 |
nub outdated |
The minimumReleaseAge window is applied without remark, as install and update apply it; the per-cell marker and the footer naming the held version are gone. |
#779 |
Runtime
| Area | What changed | PR |
|---|---|---|
| Node versions | Node 23.0–23.4 route to the compat tier: module.registerHooks reached the 23.x line at 23.5.0, and those releases threw at startup under the fast tier. nub compile refuses an external-shim build targeting that band for the same reason. |
#802 |
| Node versions | --enable-source-maps is withheld on every Node 26.x below 26.8, the band affected by nodejs/node#63169. |
#784 |
| Builtins | CommonJS require("node:test"), node:sqlite, node:sea and node:test/reporters work again on Node 22.15.0–22.17.1, 23.5.0–23.11.1 and 24.0.0–24.3.0, where a registered resolve hook dropped the node: scheme (fixed upstream in 22.18, 24.4 and 25+). |
#803 |
| Loaders | A non-file: URL passes through the load hook untouched, so a custom-protocol ESM loader behaves as it does on plain Node. |
#788 |
| Environment files | --env-file values are no longer $VAR-expanded, matching Node. A value holding a literal $ arrives intact. |
#789 |
| Environment files | .env.schema discovery walks from the project root up to the workspace root, so a schema at an enclosing package or at a directory without a manifest is found. |
#809 |
| Test runner | Node's default test-file coverage exclusion stays in effect when Nub adds its own exclusion for the preloaded runtime. | #798, #815 |
| Debugging | A transpiled TypeScript file reports a file: URL as its sourceURL, so editor and DevTools breakpoints match the same script identity as under node. |
#800 |
| REPL | A module-resolution error in the REPL keeps its named stack frames. | #797 |
| Blob URLs | URL.revokeObjectURL() with no argument throws ERR_MISSING_ARGS, as Node does. |
#799 |
Documentation and site
- The environment-file docs describe the current
--env-fileand.env.schemabehavior; the Varlock page's monorepo callout is updated. (#809) - The FAQ lists only the WinterTC gap global the preload defines. (
abe3a6a) - The Node-compat corpus is refreshed to Node 26.7.0 and scored under named lenses; the compat benchmark on the site carries the remeasured figures. (#785,
c93d676) - The docs pages prerender again;
?section=share links route to an on-demand variant. (dbb4ae1) - The 0.8.0 blog post's eject callout describes the collective fallback tree. (
985d122)
Testing & internals
- The repository root is a nub-identity project on
nub.lock, and CI bootstraps withnub. (#807) - A worktree that edits only
runtime/builds into an isolated target directory. (#801) - The public wiki drops research docs written as internal investigations and gains a public-content lint. (
d50b1c2) - The download-stats pipeline reads the daily snapshot ledger. (
5992582,ec69670) - A failing nubjs.com production deploy is tracked like a red trunk. (
374c253)
What's Changed
- lockfile: resolve a read against the declared package manager, not filename precedence by @colinhacks in #781
- fix(pm): make a global install produce a runnable command by @colinhacks in #773
- node: withhold --enable-source-maps across the whole Node 26.x assert regression band by @colinhacks in #784
- runtime: pass non-file URLs through the load hook untouched by @colinhacks in #788
- env: stop expanding $VAR in --env-file values, matching Node by @colinhacks in #789
- outdated: honor the release-age window silently by @colinhacks in #779
- runtime: keep the stack of a REPL module-resolution error by @colinhacks in #797
- node: keep Node's default test-file coverage exclusion when nub injects its own by @colinhacks in #798
- runtime: forward caller arguments through the revokeObjectURL wrap by @colinhacks in #799
- build: isolate the target dir when runtime/ diverges by @colinhacks in #801
- node: route Node 23.0-23.4 to the compat tier by @colinhacks in #802
- runtime: restore the node: scheme on builtins that require it by @colinhacks in #803
- repo: make the root nub-identity on nub.lock, and bootstrap CI with nub by @colinhacks in #807
- test(node-compat): refresh the Node-compat corpus to 26.7.0 and score it under named lenses by @colinhacks in #785
- transpile: report a file: URL as a stripped script's sourceURL by @colinhacks in #800
- node: restate the default coverage exclusion on argv only; remeasure the 26.7.0 corpus on merged main by @colinhacks in #815
- runtime: scan for .env.schema up to the workspace root by @colinhacks in #809
- lockfile: drop non-optional peerDependenciesMeta entries from the pnpm writer by @colinhacks in #814
Full Changelog: v0.8.0...v0.8.1