How do I simulate the global variable in Node's vm module?

30 Views Asked by At

I'm trying to use node.js's vm module for an automated test I'm writing, as far as I can tell, it doesn't build an environment with the global variable:

$ node -p 'const vm = require("node:vm"); const context = {}; vm.runInNewContext("global.foo=5;", context); console.log(context);'
evalmachine.<anonymous>:1
global.foo=5;
^

ReferenceError: global is not defined

It does seem to come with globalThis, though:

$ node -p 'const vm = require("node:vm"); const context = {}; vm.runInNewContext("globalThis.foo=5;", context); console.log(context);'
{ foo: 5 }
undefined

I'm not sure why or even how it's missing global, but how do I create a vm context with it?

Note: I'm going to answer my question but I'm not confident it's a good solution. Let me know if it can be improved.

1

There are 1 best solutions below

0
Daniel Kaplan On

You can define global in context as a reference to itself:

$ node -p 'const vm = require("node:vm"); const context = {}; context.global = context; vm.runInNewContext("global.foo=5;", context); console.log(context);'
<ref *1> { global: [Circular *1], foo: 5 }
undefined

This more elaborate example shows that globalThis === global within the context:

$ node -p 'const vm = require("node:vm"); const context = { console }; context.global = context; vm.runInNewContext("global.foo=5; console.log(\"vm.runInNewContext\", globalThis.foo)", context); console.log("outside", context); console.log("outside foo", context.foo);'
vm.runInNewContext 5
outside <ref *1> {
  console: Object [console] {
    log: [Function: log],
    warn: [Function: warn],
    dir: [Function: dir],
    time: [Function: time],
    timeEnd: [Function: timeEnd],
    timeLog: [Function: timeLog],
    trace: [Function: trace],
    assert: [Function: assert],
    clear: [Function: clear],
    count: [Function: count],
    countReset: [Function: countReset],
    group: [Function: group],
    groupEnd: [Function: groupEnd],
    table: [Function: table],
    debug: [Function: debug],
    info: [Function: info],
    dirxml: [Function: dirxml],
    error: [Function: error],
    groupCollapsed: [Function: groupCollapsed],
    Console: [Function: Console],
    profile: [Function: profile],
    profileEnd: [Function: profileEnd],
    timeStamp: [Function: timeStamp],
    context: [Function: context],
    createTask: [Function: createTask]
  },
  global: [Circular *1],
  foo: 5
}
outside foo 5
undefined