-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lib: basic support for primordials in undici #55783
base: main
Are you sure you want to change the base?
Conversation
Review requested:
|
Actually you don't need that,
node/lib/eslint.config_partial.mjs Lines 252 to 253 in c42d846
|
@aduh95 ah, so maybe I would need to do something like this instead? const globals = { WebAssembly, URL, URLSearchParams }; // probably export this from a file next to primordials.js
return undici ??= require('internal/deps/undici/undici')(primordials, globals); |
No it's not what I meant, I'm saying the full diff should be: diff --git a/deps/undici/undici.js b/deps/undici/undici.js
index 1a2312842a6..ef0becdda26 100644
--- a/deps/undici/undici.js
+++ b/deps/undici/undici.js
@@ -1,4 +1,10 @@
"use strict";
+const {
+ globalThis,
+} = primordials;
+const { AbortController } = require('internal/abort_controller');
+const { URL } = require('internal/url');
+const { WebAssembly } = globalThis;
var __defProp = Object.defineProperty;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); I.e. you do not need to wrap the undici source again $ # Before this change:
$ node -p 'delete globalThis.globalThis;fetch("data:application/json,[]").then(e => e.json())'
node:internal/deps/undici/undici:7970
return globalThis[globalDispatcher];
^
ReferenceError: globalThis is not defined
at getGlobalDispatcher2 (node:internal/deps/undici/undici:7970:7)
at lib/global.js (node:internal/deps/undici/undici:7954:9)
at __require (node:internal/deps/undici/undici:6:50)
at node:internal/deps/undici/undici:13179:52
at BuiltinModule.compileForInternalLoader (node:internal/bootstrap/realm:398:7)
at requireBuiltin (node:internal/bootstrap/realm:429:14)
at fetch (node:internal/bootstrap/web/exposed-window-or-worker:69:28)
at [eval]:1:30
at runScriptInThisContext (node:internal/vm:209:10)
at node:internal/process/execution:118:14
Node.js v20.18.0
$ # After applying my diff:
$ ./node -p 'delete globalThis.globalThis;fetch("data:application/json,[]").then(e => e.json())'
Promise { [] } |
This PR isn't intended to be merged in its current form. Most notably it modifies
deps/undici/undici.js
which is the output from a build script.The gist of this change is that I'm working on a side project that, among other things, deletes a ton of global variables. So far all of the internal Node.js modules seem unaffected thanks to the usage of primordials. However, Undici is an external module bundled into Node.js and therefore doesn't have direct access to primordials.
I attempted to solve this by wrapping the Undici code in a function that provides the primordials as arguments. It's similar to the function that wraps CJS files to inject
__filename
. It's a pretty basic solution and I'm not sure if it's the best.It seems like wrapping and injecting primordials could be a useful pattern for any sort of vendored code to get them to be more resilient to weird changes like deletion of globals like the internal modules are.
Also note that this change is only like a "phase 1" solution where globals are made available, such as
WebAssembly
. However the change isn't resilient to, saydelete Array.prototype.push
. Fixing that would require a lot of work and would probably require an AST transform to replacearr.push(1)
withArrayPrototypePush(arr, 1)
. This could maybe be doable if the library is written in TypeScript but I suspect it would be impossible if the library is written in JavaScript.More discussion: nodejs/undici#3812