Instances of the vm.Script class contain precompiled scripts that can be
executed in specific contexts.
vm.Script Constructor
History
vm.constants.USE_MAIN_CONTEXT_DEFAULT_LOADER.importModuleDynamically parameter.produceCachedData is deprecated in favour of script.createCachedData().cachedData and produceCachedData options are supported now.new vm.Script(code, options?): vm.Script
stringstring'evalmachine.<anonymous>'.number0.number0.Buffer | TypedArray | DataViewBuffer or
TypedArray, or DataView with V8's code cache data for the supplied
source. When supplied, the cachedDataRejected value will be set to
either true or false depending on acceptance of the data by V8.booleantrue and no cachedData is present, V8
will attempt to produce code cache data for code. Upon success, a
Buffer with V8's code cache data will be produced and stored in the
cachedData property of the returned vm.Script instance.
The cachedDataProduced value will be set to either true or false
depending on whether code cache data is produced successfully.
This option is deprecated in favor of script.createCachedData().
Default: false.Function | vm.constants.USE_MAIN_CONTEXT_DEFAULT_LOADERimport() is called. This option is part of the
experimental modules API. We do not recommend using it in a production
environment. For detailed information, see
Support of dynamic import() in compilation APIs.If options is a string, then it specifies the filename.
Creating a new vm.Script object compiles code but does not run it. The
compiled vm.Script can be run later multiple times. The code is not bound to
any global object; rather, it is bound before each run, just for that run.
When cachedData is supplied to create the vm.Script, this value will be set
to either true or false depending on acceptance of the data by V8.
Otherwise the value is undefined.
script.createCachedData(): Buffer
BufferCreates a code cache that can be used with the Script constructor's
cachedData option. Returns a Buffer. This method may be called at any
time and any number of times.
The code cache of the Script doesn't contain any JavaScript observable
states. The code cache is safe to be saved along side the script source and
used to construct new Script instances multiple times.
Functions in the Script source can be marked as lazily compiled and they are
not compiled at construction of the Script. These functions are going to be
compiled when they are invoked the first time. The code cache serializes the
metadata that V8 currently knows about the Script that it can use to speed up
future compilations.
const script = new vm.Script(` function add(a, b) { return a + b; } const x = add(1, 2); `); const cacheWithoutAdd = script.createCachedData(); // In `cacheWithoutAdd` the function `add()` is marked for full compilation // upon invocation. script.runInThisContext(); const cacheWithAdd = script.createCachedData(); // `cacheWithAdd` contains fully compiled function `add()`.
script.runInContext(contextifiedObject, options?): any
Objectvm.createContext() method.Objectbooleantrue, if an Error occurs
while compiling the code, the line of code causing the error is attached
to the stack trace. Default: true.anyRuns the compiled code contained by the vm.Script object within the given
contextifiedObject and returns the result. Running code does not have access
to local scope.
The following example compiles code that increments a global variable, sets
the value of another global variable, then execute the code multiple times.
The globals are contained in the context object.
import { createContext, Script } from 'node:vm'; const context = { animal: 'cat', count: 2, }; const script = new Script('count += 1; name = "kitty";'); createContext(context); for (let i = 0; i < 10; ++i) { script.runInContext(context); } console.log(context); // Prints: { animal: 'cat', count: 12, name: 'kitty' }
const { createContext, Script } = require('node:vm'); const context = { animal: 'cat', count: 2, }; const script = new Script('count += 1; name = "kitty";'); createContext(context); for (let i = 0; i < 10; ++i) { script.runInContext(context); } console.log(context); // Prints: { animal: 'cat', count: 12, name: 'kitty' }
Using the timeout or breakOnSigint options will result in new event loops
and corresponding threads being started, which have a non-zero performance
overhead.
script.runInNewContext(contextObject?, options?): any
Object | vm.constants.DONT_CONTEXTIFY | undefinedvm.constants.DONT_CONTEXTIFY or an object that will be contextified.
If undefined, an empty contextified object will be created for backwards compatibility.Objectbooleantrue, if an Error occurs
while compiling the code, the line of code causing the error is attached
to the stack trace. Default: true.integercode
before terminating execution. If execution is terminated, an Error
will be thrown. This value must be a strictly positive integer.booleantrue, receiving SIGINT
(Ctrl+C) will terminate execution and throw an
Error. Existing handlers for the event that have been attached via
process.on('SIGINT') are disabled during script execution, but continue to
work after that. Default: false.string'VM Context i', where i is an ascending numerical index of
the created context.stringurl.origin property of a URL object. Most notably,
this string should omit the trailing slash, as that denotes a path.
Default: ''.ObjectstringafterEvaluate, microtasks (tasks
scheduled through Promises and async functions) will be run immediately
after the script has run. They are included in the timeout and
breakOnSigint scopes in that case.anyThis method is a shortcut to script.runInContext(vm.createContext(options), options).
It does several things at once:
- Creates a new context.
- If
contextObjectis an object, contextifies it with the new context. IfcontextObjectis undefined, creates a new object and contextifies it. IfcontextObjectisvm.constants.DONT_CONTEXTIFY, don't contextify anything. - Runs the compiled code contained by the
vm.Scriptobject within the created context. The code does not have access to the scope in which this method is called. - Returns the result.
The following example compiles code that sets a global variable, then executes
the code multiple times in different contexts. The globals are set on and
contained within each individual context.
import { constants, Script } from 'node:vm'; const script = new Script('globalVar = "set"'); const contexts = [{}, {}, {}]; contexts.forEach((context) => { script.runInNewContext(context); }); console.log(contexts); // Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }] // This would throw if the context is created from a contextified object. // constants.DONT_CONTEXTIFY allows creating contexts with ordinary // global objects that can be frozen. const freezeScript = new Script('Object.freeze(globalThis); globalThis;'); const frozenContext = freezeScript.runInNewContext(constants.DONT_CONTEXTIFY);
const { constants, Script } = require('node:vm'); const script = new Script('globalVar = "set"'); const contexts = [{}, {}, {}]; contexts.forEach((context) => { script.runInNewContext(context); }); console.log(contexts); // Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }] // This would throw if the context is created from a contextified object. // constants.DONT_CONTEXTIFY allows creating contexts with ordinary // global objects that can be frozen. const freezeScript = new Script('Object.freeze(globalThis); globalThis;'); const frozenContext = freezeScript.runInNewContext(constants.DONT_CONTEXTIFY);
script.runInThisContext
History
breakOnSigint option is supported now.script.runInThisContext(options?): any
Objectbooleantrue, if an Error occurs
while compiling the code, the line of code causing the error is attached
to the stack trace. Default: true.anyRuns the compiled code contained by the vm.Script within the context of the
current global object. Running code does not have access to local scope, but
does have access to the current global object.
The following example compiles code that increments a global variable then
executes that code multiple times:
import { Script } from 'node:vm'; global.globalVar = 0; const script = new Script('globalVar += 1', { filename: 'myfile.vm' }); for (let i = 0; i < 1000; ++i) { script.runInThisContext(); } console.log(globalVar); // 1000
const { Script } = require('node:vm'); global.globalVar = 0; const script = new Script('globalVar += 1', { filename: 'myfile.vm' }); for (let i = 0; i < 1000; ++i) { script.runInThisContext(); } console.log(globalVar); // 1000
When the script is compiled from a source that contains a source map magic comment, this property will be set to the URL of the source map.
import vm from 'node:vm'; const script = new vm.Script(` function myFunc() {} //# sourceMappingURL=sourcemap.json `); console.log(script.sourceMapURL); // Prints: sourcemap.json
const vm = require('node:vm'); const script = new vm.Script(` function myFunc() {} //# sourceMappingURL=sourcemap.json `); console.log(script.sourceMapURL); // Prints: sourcemap.json