Repository navigation
perf(ext/node): convert child_process, cluster, console to lazy-loaded JS - #33925
Conversation
…d JS
Convert internal polyfill modules from ESM to IIFE lazy-loaded scripts
to reduce startup overhead. Converted files:
- internal/child_process.ts
- internal/cluster/{child,linkedlist,primary,round_robin_handle,shared_handle,utils,worker}.ts
- internal/console/constructor.mjs
Also update consumers (child_process.ts, cluster.ts, console.ts,
01_require.js) to use core.loadExtScript instead of ESM imports.
fibibot
left a comment
There was a problem hiding this comment.
Substance walk on the 9-file IIFE conversion — pattern matches the established series (#33876/#33881/#33882/#33897/#33902/#33913/#33917/#33919). Holding at COMMENT pending the 10 in-progress shards.
What I verified
Registration at ext/node/lib.rs:425-433 — 9 files moved from the eager esm block to the lazy_loaded_esm block. ✓
Consumer wrappers at child_process.ts, cluster.ts, console.ts — all switch from ESM import {...} to core.loadExtScript(...) destructure. The child_process.ts consumer at :13-22 correctly destructures default: internalChildProcess to recover the prior import internalChildProcess from ... shape. The ChildProcessOptions entry in that destructure is benign — it's a TS interface declared with export interface ChildProcessOptions { ... } at internal/child_process.ts:737, used only as a type annotation in child_process.ts (e.g. type ForkOptions = ChildProcessOptions;), so the runtime undefined value never gets read. ✓
IIFE pattern in internal/child_process.ts at :9-12 — (function () { const { core } = globalThis.__bootstrap; ... return { ... default: { ... } }; })(). Lazy loaders correctly used for circular-risk deps:
node:stream(Readable/WritablevialazyStream().Transformetc.)node:process(note: ends inlazyProcess().defaultaccess in cluster/primary.ts:50 — same.defaultpattern that was the64512f49fix in #33919, applied correctly here)node:net,node:dgram(used atsetupChanneltime, not module-init time)- Internal
dgram.tsandudp_wrap.tsvia lazy loaders
internal/cluster/primary.ts conversion uses lazyChildProcess() for fork() (which would otherwise be a circular cluster → child_process → cluster import cycle), and resolves process and path inside init() so the cluster module can finish loading before process.cwd()-style calls fire. ✓
internal/console/constructor.mjs stays .mjs extension — IIFE conversion preserves the kBindStreamsLazy/kBindProperties patterns. ✓
CI
122 success | 10 in_progress | 1 skipped | 0 fail
The 10 in-progress are the slow Windows-aarch64 + node_compat (3/3) shards; nothing has flagged. Substance is APPROVE-quality modulo CI completion — will upgrade once the remaining shards land green.
…d JS (denoland#33925) - Convert 9 internal polyfill modules from ESM to IIFE lazy-loaded scripts to reduce startup overhead - Converted: `internal/child_process.ts`, `internal/cluster/{child,linkedlist,primary,round_robin_handle,shared_handle,utils,worker}.ts`, `internal/console/constructor.mjs` - Update consumers (`child_process.ts`, `cluster.ts`, `console.ts`, `01_require.js`) to use `core.loadExtScript` instead of ESM imports - Move file registrations in `lib.rs` from `esm_modules` to `lazy_loaded_esm_sources`
Summary
internal/child_process.ts,internal/cluster/{child,linkedlist,primary,round_robin_handle,shared_handle,utils,worker}.ts,internal/console/constructor.mjschild_process.ts,cluster.ts,console.ts,01_require.js) to usecore.loadExtScriptinstead of ESM importslib.rsfromesm_modulestolazy_loaded_esm_sourcesTest plan
child_processsmoke test (execSync, spawnSync)clustersmoke test (isPrimary/isWorker)consolesmoke test (Console constructor)