|
1 | 1 | # Node runtime selection |
2 | 2 |
|
3 | | -The Node.js a test worker runs on is a **User Node runtime** — chosen by the extension from the user's own environment, the PATH `node` first and then the `node` the user's interactive shell would give them — and it must satisfy a uniform floor, `^22.18.0 || >=23.6.0`. The **VS Code Node runtime** is never a candidate. When nothing satisfies the floor, the test stack reports a status and runs nothing. |
| 3 | +The Node.js a test worker runs on is a **User Node runtime** — chosen by the extension from the user's own environment, the PATH `node` first and then the `node` the user's interactive shell would give them — and it must satisfy a uniform floor, `^22.18.0 || >=24.3.0`. The **VS Code Node runtime** is never a candidate. When nothing satisfies the floor, the test stack reports a status and runs nothing. |
4 | 4 |
|
5 | | -## Why the floor is `^22.18.0 || >=23.6.0` |
| 5 | +## Why the floor is `^22.18.0 || >=24.3.0` |
6 | 6 |
|
7 | | -The strictest thing a worker does is load an `rstack.config.*`, which rstack's shipped shim loads through `@rstackjs/load-config` with `loader: 'native'`. That path rethrows with no jiti fallback (`rstack-cli` `packages/rstack/src/config.ts:174`, bundled verbatim into `rstack@0.4.0`'s `dist/687.js`), and `native` never consults `process.features.typescript` — it calls `import()` directly. So the worker needs Node's native TypeScript stripping, which was unflagged in 23.6.0 and backported to the LTS line in 22.18.0. That release history is why the floor is a disjunction rather than a single version: 23.0–23.5 compare above 22.18.0 yet predate the unflagging, and `^22.18.0 || >=23.6.0` names exactly the versions that strip by default. |
| 7 | +The strictest thing a worker does is load an `rstack.config.*`, which rstack's shipped shim loads through `@rstackjs/load-config` with `loader: 'native'`. That path rethrows with no jiti fallback (`rstack-cli` `packages/rstack/src/config.ts:174`, bundled verbatim into `rstack@0.4.0`'s `dist/687.js`), and `native` never consults `process.features.typescript` — it calls `import()` directly. So the worker needs Node's native TypeScript stripping, which was unflagged in 23.6.0 and backported to the LTS line in 22.18.0; that is the type-stripping lower bound. |
8 | 8 |
|
9 | | -Native type stripping is the _only_ thing on the worker's path that needs more than the declared `engines` of the packages involved: `@rstest/core` 0.11.6 and `@rsbuild/core` declare `^20.19.0 || >=22.12.0`, `rstack` 0.4.0 declares `>=22.12.0`, and `Module.registerHooks` (used by rstack's `freshImport`, added in 22.15) has a three-level fallback. |
| 9 | +The supported rstack line adds a narrower declared contract. Since rstack 0.7.0, `engines.node` is `^22.18.0 || >=24.3.0`: Node 23 is unsupported, and Node 24.0–24.2 still emits the experimental type-stripping warning that 24.3.0 removes ([rstackjs/rstack-cli#427](https://github.com/rstackjs/rstack-cli/pull/427)). The extension therefore intersects native type-stripping availability with rstack's declared engines rather than accepting a runtime the supported toolchain rejects. The range follows those engines as that contract changes. |
| 10 | + |
| 11 | +Other packages on the worker path allow older runtimes: `@rstest/core` and `@rsbuild/core` declare `^20.19.0 || >=22.12.0`, and `Module.registerHooks` (used by rstack's `freshImport`, added in 22.15) has a three-level fallback. |
10 | 12 |
|
11 | 13 | ## Considered options |
12 | 14 |
|
13 | | -**A per-project floor** — 22.18.0 only for projects driven by an `rstack.config.*`, 22.12.0 for a native `rstest.config.*`. Rejected: it buys back Node 20.19–22.17 at the cost of a second code path through every call site. Node 20 left support on 2026-04-30, so the users it genuinely serves are those on Node 22.12–22.17 — a supported LTS line, needing only a patch-level update within 22.x. That is a low-friction ask, and one uniform floor is a support contract the README and the status bar can each state in one sentence. |
| 15 | +**A per-project floor** — the full rstack floor only for projects driven by an `rstack.config.*`, with looser floors where package contracts allow. Rejected: it buys back Node 20.19–22.17, Node 23 and Node 24.0–24.2 at the cost of a second code path through every call site. Node 20 is out of support; Node 23 is an unsupported odd-numbered line; and users on Node 22 or 24 need only a patch-level update within that line. That is a low-friction ask, and one uniform floor is a support contract the README and the status bar can each state in one sentence. |
14 | 16 |
|
15 | 17 | **A capability probe instead of a version check** — asking each candidate for `process.features.typescript` rather than comparing semver. Rejected: `process.features.typescript` is itself Stability 1.2 (release candidate) and its value set has moved (`"transform"` existed on 22.18–25.1, removed in 26.0.0). More decisively, `loader: 'native'` never reads it, so the probe would not be testing the condition that actually fails. A floor is a contract; contracts are declared, not sniffed. |
16 | 18 |
|
|
0 commit comments