| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
|
Review requested:
|
Sorry, something went wrong.
Codecov Report❌ Patch coverage is 99.34641% with 1 line in your changes missing coverage. Please review.
@@ Coverage Diff @@
## main #59929 +/- ##
=======================================
Coverage 88.55% 88.55%
=======================================
Files 704 704
Lines 208081 208127 +46
Branches 40004 40022 +18
=======================================
+ Hits 184265 184310 +45
- Misses 15809 15827 +18
+ Partials 8007 7990 -17
... and 35 files with indirect coverage changes 🚀 New features to boost your workflow:
|
Sorry, something went wrong.
Sorry, something went wrong.
|
This is necessary to fix known issues with sync/async loader hook interop. Can I get some reviews please? @nodejs/loaders |
Sorry, something went wrong.
There was a problem hiding this comment.
Thank you, I've always disliked this “null means this“ pattern and at least this makes it clearer and more explicit. Maybe when we remove the async hooks we can get rid of this pattern.
Sorry, something went wrong.
Sorry, something went wrong.
Sorry, something went wrong.
Sorry, something went wrong.
Sorry, something went wrong.
This relaxes the validation in sync hooks so that it accepts the quirky nullish source returned by the default step of the async loader when the module being loaded is CommonJS. When there are no customization hooks registered, a saner synchronous default load step is used to use a property instead of a reset nullish source to signify that the module should go through the CJS monkey patching routes and reduce excessive reloading from disk.
Sorry, something went wrong.
|
Addressed the comments and CI is finally green. Can you take a look again? Thanks! @GeoffreyBooth @JakobJingleheimer |
Sorry, something went wrong.
* chore: bump node in DEPS to v24.11.1 * src: add a default branch for module phase nodejs/node#60261 * src: conditionally disable source phase imports by default nodejs/node#60364 * chore: update patches * src: update locks to use DictionaryTemplate and other minor cleanups nodejs/node#60061 * deps: update simdjson to 4.0.7 nodejs/node#59883 * test: move sea tests into test/sea nodejs/node#60250 * fixup deps: update simdjson to 4.0.7a * src: conditionally disable source phase imports by default nodejs/node#60364 * module: handle null source from async loader hooks in sync hooks nodejs/node#59929 * Revert "src: conditionally disable source phase imports by default" This reverts commit 5f85b84. * src: allow disabling JS source phase imports nodejs/node#60364 --------- Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com> Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org> Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
* chore: bump node in DEPS to v24.11.1 * chore: bump node to v24.11.1 (main) (#48917) * chore: bump node in DEPS to v24.11.1 * src: add a default branch for module phase nodejs/node#60261 * src: conditionally disable source phase imports by default nodejs/node#60364 * chore: update patches * src: update locks to use DictionaryTemplate and other minor cleanups nodejs/node#60061 * deps: update simdjson to 4.0.7 nodejs/node#59883 * test: move sea tests into test/sea nodejs/node#60250 * fixup deps: update simdjson to 4.0.7a * src: conditionally disable source phase imports by default nodejs/node#60364 * module: handle null source from async loader hooks in sync hooks nodejs/node#59929 * Revert "src: conditionally disable source phase imports by default" This reverts commit 5f85b84. * src: allow disabling JS source phase imports nodejs/node#60364 --------- Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com> Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org> Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com> --------- Co-authored-by: electron-roller[bot] <84116207+electron-roller[bot]@users.noreply.github.com> Co-authored-by: John Kleinschmidt <jkleinsc@electronjs.org> Co-authored-by: Shelley Vohr <shelley.vohr@gmail.com>
This relaxes the validation in sync hooks so that it accepts the quirky nullish source returned by the default step of the async loader when the module being loaded is CommonJS. When there are no customization hooks registered, a saner synchronous default load step is used to use a property instead of a reset nullish source to signify that the module should go through the CJS monkey patching routes and reduce excessive reloading from disk. PR-URL: nodejs#59929 Fixes: nodejs#59384 Fixes: nodejs#57327 Refs: nodejs#59666 Refs: https://github.com/dygabo/load_module_test Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Jacob Smith <jacob@frende.me>
This relaxes the validation in sync hooks so that it accepts the quirky nullish source returned by the default step of the async loader when the module being loaded is CommonJS. When there are no customization hooks registered, a saner synchronous default load step is used to use a property instead of a reset nullish source to signify that the module should go through the CJS monkey patching routes and reduce excessive reloading from disk. PR-URL: #59929 Backport-PR-URL: #62029 Fixes: #59384 Fixes: #57327 Refs: #59666 Refs: https://github.com/dygabo/load_module_test Reviewed-By: Geoffrey Booth <webadmin@geoffreybooth.com> Reviewed-By: Jacob Smith <jacob@frende.me> Fixes: #61801
module.registerHooks exists since v22.15, but its synchronous load hook rejected the nullish CommonJS source the loader returns for require()s pulled into the ESM graph (ERR_INVALID_RETURN_PROPERTY_VALUE) until nodejs/node#59929, released in 22.22.3, 24.11.1, 25.1.0 and 26.0.0. register() now throws on versions that ship registerHooks but predate the fix (< 22.22.3, <= 24.11.0, 25.0.0) so embedders can fall back to the asynchronous loader instead of crashing mid-graph. supportsSyncHooks() exposes the same check for consumers that register the hooks themselves. Refs: nodejs/node#59929
…upport module.registerHooks rejects the nullish CommonJS source the synchronous loader returns for require()s pulled into the ESM graph (ERR_INVALID_RETURN_PROPERTY_VALUE) until nodejs/node#59929, released in 22.22.3, 24.11.1, 25.1.0 and 26.0.0; note 24.0.0-24.11.0 and 25.0.0 ship registerHooks but predate it. Consult iitm's supportsSyncHooks() (which owns this capability check) and bump the fork to pick it up; unsupported versions fall back to the asynchronous loader. Refs: nodejs/node#59929
Extracting `supportsSyncHooks` into its own module added a relative `import './supports-sync-hooks.mjs'` to `create-hook.mjs`. The `specifiers-map-cleanup` loader evaluates a copy of `create-hook.mjs` from a `data:` URL, which has no hierarchical base, and only rewrote `./lib/...` imports to absolute file URLs. The new sibling import stayed relative and threw `ERR_INVALID_URL`, failing CI on every Node >= 20. 1. Rewrite every relative `./...` import in the loader, not just `./lib/...`, so any sibling module `create-hook.mjs` imports resolves from the `data:` URL. 2. Read the version with `parseInt` + `indexOf` instead of a regex match mapped into a destructure. The major decides every release line except 22/24/25, so the minor and patch are parsed lazily and only when one of those is hit. 3. Document `supportsSyncHooks` and the real support matrix (22.22.3, 24.11.1, 25.1.0, 26.0.0) in the README and `register-hooks.d.ts`; the prior text pointed at the `module.registerHooks()` introduction versions, which ship the API but predate the nullish-CommonJS-source fix. Refs: nodejs/node#59929
Extracting `supportsSyncHooks` into its own module added a relative `import './supports-sync-hooks.mjs'` to `create-hook.mjs`. The `specifiers-map-cleanup` loader evaluates a copy of `create-hook.mjs` from a `data:` URL, which has no hierarchical base, and only rewrote `./lib/...` imports to absolute file URLs. The new sibling import stayed relative and threw `ERR_INVALID_URL`, failing CI on every Node >= 20. 1. Rewrite every relative `./...` import in the loader, not just `./lib/...`, so any sibling module `create-hook.mjs` imports resolves from the `data:` URL. 2. Read the version with `parseInt` + `indexOf` instead of a regex match mapped into a destructure. The major decides every release line except 22/24/25, so the minor and patch are parsed lazily and only when one of those is hit. 3. Document `supportsSyncHooks` and the real support matrix (22.22.3, 24.11.1, 25.1.0, 26.0.0) in the README and `register-hooks.d.ts`; the prior text pointed at the `module.registerHooks()` introduction versions, which ship the API but predate the nullish-CommonJS-source fix. Refs: nodejs/node#59929
## Problem tsx uses the sync `module.registerHooks()` path (no loader worker thread) only once Node can re-enter `Module._load` from sync hooks ([nodejs/node#59929](nodejs/node#59929)). That landed in v24.11.1 / v25.1.0 and was **also backported to v22.22.3**, but the gate had no 22.x entry — so v22.22.3+ kept taking the slower async `module.register()` path. ## Changes - Add `[22, 22, 3]` to the `moduleRegisterHooksCjsReload` gate. v22.22.2 and earlier stay on the async path; v22.22.3+ now uses sync hooks. - Bump the 22.x CI matrix entry `22.22.2` → `22.22.3` so CI exercises the newly-enabled sync path on the 22 line. Verified the backport is behaviorally complete: the full suite (incl. CJS-interop, `require.cache`, watch, version-sensitive) passes with Node 22.22.3 as the runner. Startup on Node 22.22.3, 1000 modules (min of 6 runs, M5 Pro): ``` async (before) sync (this PR) hooks-passthrough 437ms 190ms esm-ts 694ms 337ms ```
The Frida-removal rationale cited the pre-registerHooks breakage history but skipped the episode where the new API and Module._load broke each other: across Node 22.16-22.18 and the 23.x/24.x lines, registering sync hooks rerouted CJS off Module._load entirely (dygabo/load_module_test is the canonical reproducer), plain hooks died with ERR_INVALID_RETURN_PROPERTY_VALUE (nodejs/node#59384), mixing register() with registerHooks() fed CJS a null source (nodejs/node#57327), and nodejs/node#59666 catalogued the rest. Fixed by nodejs/node#59929 and nodejs/node#60380 - the same fix train (v22.22.3 / v24.11.1 / v25.1.0) already cited as iitm's sync-mode version floor elsewhere in the README. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016SaeYZzjXdWXGVMTDHRXQK
hooks/interplay-matrix runs self-contained scenarios (in the spirit of dygabo/load_module_test) against a ladder of official Node builds bracketing the nodejs/node#59929 fix train, plus this repo's real runtime hook via the ABI-stable napi addon. pnpm matrix rebuilds matrix.md. What the ladder shows: with a pure-passthrough sync load hook registered, a Module._load monkey-patch never sees import-ed CJS on 22.15.0-22.22.2 and 24.10.0-24.11.0, flipping to visible at exactly 22.22.3 and 24.11.1 - the blinding, empirically pinned to the fix boundary. The hook-fed synthetic require carries neither require.extensions nor require.cache until 24.18.0 and still carries neither anywhere on 22.x (22.23.1 included). Plain require() stayed on Module._load throughout, and the exports tap passes on every rung because it never depended on the patch point - the operative fact for Lambda runtimes that may sit on pre-fix minors (AWS applies Node minor updates on its own cadence; the base images rebuild daily without exposing the embedded minor, so process.version in a live function is the only ground truth). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016SaeYZzjXdWXGVMTDHRXQK
The `dx` CLI preload module (apps/cli/src/adapters/azure-monitor/instrumentation.ts) used `module.register()` from node:module to install the import-in-the-middle ESM hook before any HTTP client libraries are loaded. Since Node.js marked this API as deprecated (DEP0205), every CLI invocation printed: ``` (node:XXXXX) [DEP0205] DeprecationWarning: `module.register()` is deprecated. Use `module.registerHooks()` instead. ``` import-in-the-middle@3.3.2 ships a synchronous alternative based on `module.registerHooks()` (register-hooks.mjs), which avoids the deprecated API and the message-channel round-trip entirely. It's only supported on Node.js versions where a related core bug (nodejs/node#59929) is fixed: `>=22.22.3, >=24.11.1, >=25.1.0, >=26.0.0`. Since apps/cli declares `engines.node: >=22.0.0`, a wider range, this change adds a dual path: - Use the synchronous `registerHooks()` API when `supportsSyncHooks()` reports the running Node.js correctly supports it. - Otherwise fall back to the existing `module.register()` + `createAddHookMessageChannel`/`waitForAllMessagesAcknowledged` approach, so older supported Node.js versions keep working exactly as before (with the same deprecation warning, since Node itself hasn't removed the old API). Also adds an ambient module declaration for `import-in-the-middle/register-hooks.mjs`, since the package ships `register-hooks.d.ts` rather than `register-hooks.d.mts`, which TypeScript's `node16`/`nodenext` module resolution doesn't associate with the `.mjs` file. Verified manually on Node.js 26 (sync path, no warning) and by temporarily forcing the fallback branch (old behavior, warning still present as expected on unsupported Node versions). Resolves: CES-2232
Two regressions from installing the load hook at the tracer entrypoint. The hook was registered on any runtime with `module.registerHooks`, but the API predates nodejs/node#59929 (fixed in 22.22.3, 24.11.1, 25.1.0 and 26.0.0). Below that fix a registered load hook throws ERR_INVALID_RETURN_PROPERTY_VALUE on the nullish CommonJS source Node reports for builtins, breaking every process that loads the tracer — the electron, kafkajs and Node 24.0.0 guardrails suites. `register.js` already gated on exactly this; the entrypoint hook now shares that gate through import-in-the-middle's import-free `supports-sync-hooks.mjs` and falls back to the compile hook below it. The hook also skipped every non-CommonJS format, but `require()` of an ESM package reaches `Module._compile` with `format: 'module'`, so the compile fallback rewrote it and the load hook did not. That silently dropped Orchestrion instrumentation for require(esm) targets such as `@anthropic-ai/claude-agent-sdk/sdk.mjs`. Gate on the `require` condition instead, which Node reports for exactly the loads the compile fallback saw: the CommonJS entrypoint, CommonJS dependencies and require(esm), never `import`. Both cases are pinned by tests that fail without their guard, the second using a spoofed `process.versions.node` to reach the unfixed-runtime branch. The spec also drops its hand-rolled copy of the version table in favour of the same `supportsSyncHooks()` predicate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two regressions from installing the load hook at the tracer entrypoint. The hook was registered on any runtime with `module.registerHooks`, but the API predates nodejs/node#59929 (fixed in 22.22.3, 24.11.1, 25.1.0 and 26.0.0). Below that fix a registered load hook throws ERR_INVALID_RETURN_PROPERTY_VALUE on the nullish CommonJS source Node reports for builtins, breaking every process that loads the tracer — the electron, kafkajs and Node 24.0.0 guardrails suites. `register.js` already gated on exactly this; the entrypoint hook now shares that gate through import-in-the-middle's import-free `supports-sync-hooks.mjs` and falls back to the compile hook below it. The hook also skipped every non-CommonJS format, but `require()` of an ESM package reaches `Module._compile` with `format: 'module'`, so the compile fallback rewrote it and the load hook did not. That silently dropped Orchestrion instrumentation for require(esm) targets such as `@anthropic-ai/claude-agent-sdk/sdk.mjs`. Gate on the `require` condition instead, which Node reports for exactly the loads the compile fallback saw: the CommonJS entrypoint, CommonJS dependencies and require(esm), never `import`. Both cases are pinned by tests that fail without their guard, the second using a spoofed `process.versions.node` to reach the unfixed-runtime branch. The spec also drops its hand-rolled copy of the version table in favour of the same `supportsSyncHooks()` predicate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two regressions from installing the load hook at the tracer entrypoint. The hook was registered on any runtime with `module.registerHooks`, but the API predates nodejs/node#59929 (fixed in 22.22.3, 24.11.1, 25.1.0 and 26.0.0). Below that fix a registered load hook throws ERR_INVALID_RETURN_PROPERTY_VALUE on the nullish CommonJS source Node reports for builtins, breaking every process that loads the tracer — the electron, kafkajs and Node 24.0.0 guardrails suites. `register.js` already gated on exactly this; the entrypoint hook now shares that gate through import-in-the-middle's import-free `supports-sync-hooks.mjs` and falls back to the compile hook below it. The hook also skipped every non-CommonJS format, but `require()` of an ESM package reaches `Module._compile` with `format: 'module'`, so the compile fallback rewrote it and the load hook did not. That silently dropped Orchestrion instrumentation for require(esm) targets such as `@anthropic-ai/claude-agent-sdk/sdk.mjs`. Gate on the `require` condition instead, which Node reports for exactly the loads the compile fallback saw: the CommonJS entrypoint, CommonJS dependencies and require(esm), never `import`. Both cases are pinned by tests that fail without their guard, the second using a spoofed `process.versions.node` to reach the unfixed-runtime branch. The spec also drops its hand-rolled copy of the version table in favour of the same `supportsSyncHooks()` predicate. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
| Back | FazBrowse Home | New Git URL |
This relaxes the validation in sync hooks so that it accepts the quirky nullish source returned by the default step of the async loader when the module being loaded is CommonJS. When there are no customization hooks registered, a saner synchronous default load step is used to use a property instead of a reset nullish source to signify that the module should go through the CJS monkey patching routes and reduce excessive reloading from disk.
Fixes: #59384
Fixes: #57327
Refs: #59666
Refs: https://github.com/dygabo/load_module_test