mirror of
https://github.com/HeyPuter/node-worker.git
synced 2026-11-13 18:34:31 -10:00
`require("node:repl")` was ENOENT: the module was never registered, and
registering it was not one line because `lib/repl.js` reaches for machinery
this runtime had no reason to have.
`internalBinding('contextify')` is the piece it genuinely needs, and only for
three things — `makeContextifyScript` and the two SIGINT watchdogs. It is the
same indirect eval `node/vm.ts` already was, so that file now builds its
`Script` on this one rather than keeping a second copy: `repl.js:106` lifts
`vm.Script.prototype.runInThisContext` off the public vm and applies it to a
script the internal binding built, so the two have to be one function over one
set of fields. The constructor compiles eagerly, which it must — an input that
throws there is what makes the REPL offer its `...` continuation instead of
reporting an error.
Everything else is weight. Pulling `repl.js` in unmodified drags node's whole
module system behind it, and the build stopped finishing rather than failing:
`commonjs({ dynamicRequireTargets: ["node_core/**/*.js"] })` means one dynamic
`require()` anywhere in the graph bundles every JavaScript file in the node
checkout — `benchmark/`, `deps/v8/test/`, the lot — and
`internal/modules/helpers.js:404` has one. `internal/util/inspector` was the
other half, reaching `internal/process/execution` and so
`internal/modules/typescript` and a 3.3 MB TypeScript stripper. Seven overrides
cut that back; the worker bundle is 4.6s again, against 4.6s before repl existed
and never-finishing with it.
`lib/vm.js` is an override for a different reason: without it a `require('vm')`
from inside the node tree got upstream's while a script's `require("node:vm")`
got ours. Two different `vm`s, and the REPL is the first module in the tree to
ask for one.
The rest are things only running it could find: `process.addUncaughtException-
CaptureCallback` (node 25's replacement for repl's domain-based error routing —
absent, the constructor throws and there is no prompt at all), `overrideStack-
Trace`, `isErrorStackTraceLimitWritable`, `decorateErrorStack`,
`BuiltinModule.getSchemeOnlyModuleNames`, and `SKIP_SYMBOLS`.
Two known gaps, both from the same absence. There is no V8 inspector in a
Worker, so completing a `const` declared at the prompt — which node does through
`Runtime.globalLexicalScopeNames` — does not work, though completing a property
does. And an evaluation cannot be interrupted: indirect `eval` is not something
V8 can be broken into, so `breakEvalOnSigint` is off and a runaway loop needs
killing from outside.
Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>