You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
repl / eval: CommonJS globals leak into ESM modules #30842
I think the only way to fix this would be some trickery with virtual with contexts (like the context_extensions option of CompileFunctionInContext). @hashseed does adding such an option to normal script compilation seem reasonable?
Imo repl does not have to be spec compliant. Also there is no spec for require.
i mean ideally we want to avoid cjs locals leaking into modules (and other places). if v8 is not willing to accept such a change we can call this "won't fix" (and i won't be that broken up about it) but imo it would be nice to fix.
note that according to the OP it happens for node --eval as well, so it's not just the repl.
I think you misread the first paragraph: It sounds like in the --eval case, the module logs undefined as expected. This only happens in the repl.
@devsnek Would it be possible to use the RuntimeAgent.evaluate for the repl with require from the console API instead from global? That should prevent it from leaking into the global scope and it wouldn't appear in "normal" code while still working in the repl expressions. That would also move it closer to the way the repl in devtools/debug clients works.
@jkrems that's not quite true. --eval with --input-type=module does the right thing but the commonjs variables are leaked when node --eval is used without --input-type=module.
Reacted by Jordan Harband, Jan Olaf Martin and ExE Boss
Inside script the commonjs variables are function arguments created by vm.compileFunction so I assume they're being copied to global to become available inside vm.runInThisContext.
I wish there was a comment in that file explaining why we're not using the typical function wrapper. Is it "because it would be a breaking change" at this point..? First level of blame doesn't show anything obvious.
@jkrems inspector doesn't introduce new magic scope. in fact, that would also be an issue with the virtual with scope, so i guess that won't work either...
with repl we can transform the code arbitrarily and no one will really care, so we can fix it with enough effort, but for --eval we need to keep everything exact, and i can't think of a way to make it work.
Ah, the console API is also available for all other code running, not just the evaluated expression? That's too bad. :( The upside is that it gets automatically removed once the initial evaluation stops (doesn't survive to future ticks) but I'm not sure if that's enough for this..? As long as ESM doesn't run in the same tick, it wouldn't see the require anymore.
Since there is no viable route forward here, and the design decisions in V8 encapsulation and the Node.js REPL have been made, closing this as a "wontfix".
This issue has been marked as stale due to 210 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.
This issue has been automatically closed after 30 days of inactivity following its stale status (no activity for a total of 120 days).
If this is still relevant, feel free to reopen it or leave a comment with additional details so we can continue the discussion.
Activity
devsnek commentedon Dec 7, 2019
I think the only way to fix this would be some trickery with virtual
withcontexts (like thecontext_extensionsoption ofCompileFunctionInContext). @hashseed does adding such an option to normal script compilation seem reasonable?hashseed commentedon Dec 8, 2019
Why is this an issue? Imo repl does not have to be spec compliant. Also there is no spec for
require.ljharb commentedon Dec 8, 2019
@hashseed note that according to the OP it happens for
node --evalas well, so it's not just the repl.devsnek commentedon Dec 8, 2019
i mean ideally we want to avoid cjs locals leaking into modules (and other places). if v8 is not willing to accept such a change we can call this "won't fix" (and i won't be that broken up about it) but imo it would be nice to fix.
hybrist commentedon Dec 9, 2019
I think you misread the first paragraph: It sounds like in the
--evalcase, the module logsundefinedas expected. This only happens in the repl.@devsnek Would it be possible to use the
RuntimeAgent.evaluatefor the repl withrequirefrom the console API instead from global? That should prevent it from leaking into the global scope and it wouldn't appear in "normal" code while still working in the repl expressions. That would also move it closer to the way the repl in devtools/debug clients works.coreyfarrell commentedon Dec 9, 2019
@jkrems that's not quite true.
--evalwith--input-type=moduledoes the right thing but the commonjs variables are leaked whennode --evalis used without--input-type=module.hybrist commentedon Dec 9, 2019
Oh, we set them as globals there, too? That’s definitely weird. Don’t see why we need for —eval.
coreyfarrell commentedon Dec 9, 2019
For
--evaland--printrun without--input-type=modulethey're set here:https://github.com/nodejs/node/blob/master/lib/internal/process/execution.js#L75-L79
Inside
scriptthe commonjs variables are function arguments created byvm.compileFunctionso I assume they're being copied toglobalto become available insidevm.runInThisContext.hybrist commentedon Dec 9, 2019
I wish there was a comment in that file explaining why we're not using the typical function wrapper. Is it "because it would be a breaking change" at this point..? First level of blame doesn't show anything obvious.
devsnek commentedon Dec 9, 2019
@jkrems --print 1 needs to print 1, so wrapping it in a function wouldn't work.
hybrist commentedon Dec 9, 2019
Gotcha, thanks for the explanation! But v8-inspector and console API may be a possible path for
--print/--evalI assume?devsnek commentedon Dec 9, 2019
@jkrems inspector doesn't introduce new magic scope. in fact, that would also be an issue with the virtual
withscope, so i guess that won't work either...with repl we can transform the code arbitrarily and no one will really care, so we can fix it with enough effort, but for
--evalwe need to keep everything exact, and i can't think of a way to make it work.hybrist commentedon Dec 9, 2019
Ah, the console API is also available for all other code running, not just the evaluated expression? That's too bad. :( The upside is that it gets automatically removed once the initial evaluation stops (doesn't survive to future ticks) but I'm not sure if that's enough for this..? As long as ESM doesn't run in the same tick, it wouldn't see the
requireanymore.guybedford commentedon Mar 12, 2020
Since there is no viable route forward here, and the design decisions in V8 encapsulation and the Node.js REPL have been made, closing this as a "wontfix".
devsnek commentedon Mar 12, 2020
This is still on my list of things to fix if ever possible
github-actions commentedon Jun 27, 2026
This issue has been marked as stale due to 210 days of inactivity.
It will be automatically closed in 30 days if no further activity occurs. If this is still relevant, please leave a comment or update it to keep it open.
github-actions commentedon Jul 28, 2026
This issue has been automatically closed after 30 days of inactivity following its stale status (no activity for a total of 120 days).
If this is still relevant, feel free to reopen it or leave a comment with additional details so we can continue the discussion.