1# VM (executing JavaScript) 2 3<!--introduced_in=v0.10.0--> 4 5> Stability: 2 - Stable 6 7<!--name=vm--> 8 9<!-- source_link=lib/vm.js --> 10 11The `vm` module enables compiling and running code within V8 Virtual 12Machine contexts. **The `vm` module is not a security mechanism. Do 13not use it to run untrusted code**. 14 15JavaScript code can be compiled and run immediately or 16compiled, saved, and run later. 17 18A common use case is to run the code in a different V8 Context. This means 19invoked code has a different global object than the invoking code. 20 21One can provide the context by [_contextifying_][contextified] an 22object. The invoked code treats any property in the context like a 23global variable. Any changes to global variables caused by the invoked 24code are reflected in the context object. 25 26```js 27const vm = require('vm'); 28 29const x = 1; 30 31const context = { x: 2 }; 32vm.createContext(context); // Contextify the object. 33 34const code = 'x += 40; var y = 17;'; 35// `x` and `y` are global variables in the context. 36// Initially, x has the value 2 because that is the value of context.x. 37vm.runInContext(code, context); 38 39console.log(context.x); // 42 40console.log(context.y); // 17 41 42console.log(x); // 1; y is not defined. 43``` 44 45## Class: `vm.Script` 46<!-- YAML 47added: v0.3.1 48--> 49 50Instances of the `vm.Script` class contain precompiled scripts that can be 51executed in specific contexts. 52 53### `new vm.Script(code[, options])` 54<!-- YAML 55added: v0.3.1 56changes: 57 - version: v5.7.0 58 pr-url: https://github.com/nodejs/node/pull/4777 59 description: The `cachedData` and `produceCachedData` options are 60 supported now. 61 - version: v10.6.0 62 pr-url: https://github.com/nodejs/node/pull/20300 63 description: The `produceCachedData` is deprecated in favour of 64 `script.createCachedData()` 65--> 66 67* `code` {string} The JavaScript code to compile. 68* `options` {Object|string} 69 * `filename` {string} Specifies the filename used in stack traces produced 70 by this script. **Default:** `'evalmachine.<anonymous>'`. 71 * `lineOffset` {number} Specifies the line number offset that is displayed 72 in stack traces produced by this script. **Default:** `0`. 73 * `columnOffset` {number} Specifies the column number offset that is displayed 74 in stack traces produced by this script. **Default:** `0`. 75 * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or 76 `TypedArray`, or `DataView` with V8's code cache data for the supplied 77 source. When supplied, the `cachedDataRejected` value will be set to 78 either `true` or `false` depending on acceptance of the data by V8. 79 * `produceCachedData` {boolean} When `true` and no `cachedData` is present, V8 80 will attempt to produce code cache data for `code`. Upon success, a 81 `Buffer` with V8's code cache data will be produced and stored in the 82 `cachedData` property of the returned `vm.Script` instance. 83 The `cachedDataProduced` value will be set to either `true` or `false` 84 depending on whether code cache data is produced successfully. 85 This option is **deprecated** in favor of `script.createCachedData()`. 86 **Default:** `false`. 87 * `importModuleDynamically` {Function} Called during evaluation of this module 88 when `import()` is called. If this option is not specified, calls to 89 `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. 90 This option is part of the experimental modules API, and should not be 91 considered stable. 92 * `specifier` {string} specifier passed to `import()` 93 * `module` {vm.Module} 94 * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is 95 recommended in order to take advantage of error tracking, and to avoid 96 issues with namespaces that contain `then` function exports. 97 98If `options` is a string, then it specifies the filename. 99 100Creating a new `vm.Script` object compiles `code` but does not run it. The 101compiled `vm.Script` can be run later multiple times. The `code` is not bound to 102any global object; rather, it is bound before each run, just for that run. 103 104### `script.createCachedData()` 105<!-- YAML 106added: v10.6.0 107--> 108 109* Returns: {Buffer} 110 111Creates a code cache that can be used with the Script constructor's 112`cachedData` option. Returns a Buffer. This method may be called at any 113time and any number of times. 114 115```js 116const script = new vm.Script(` 117function add(a, b) { 118 return a + b; 119} 120 121const x = add(1, 2); 122`); 123 124const cacheWithoutX = script.createCachedData(); 125 126script.runInThisContext(); 127 128const cacheWithX = script.createCachedData(); 129``` 130 131### `script.runInContext(contextifiedObject[, options])` 132<!-- YAML 133added: v0.3.1 134changes: 135 - version: v6.3.0 136 pr-url: https://github.com/nodejs/node/pull/6635 137 description: The `breakOnSigint` option is supported now. 138--> 139 140* `contextifiedObject` {Object} A [contextified][] object as returned by the 141 `vm.createContext()` method. 142* `options` {Object} 143 * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs 144 while compiling the `code`, the line of code causing the error is attached 145 to the stack trace. **Default:** `true`. 146 * `timeout` {integer} Specifies the number of milliseconds to execute `code` 147 before terminating execution. If execution is terminated, an [`Error`][] 148 will be thrown. This value must be a strictly positive integer. 149 * `breakOnSigint` {boolean} If `true`, the execution will be terminated when 150 `SIGINT` (Ctrl+C) is received. Existing handlers for the 151 event that have been attached via `process.on('SIGINT')` will be disabled 152 during script execution, but will continue to work after that. If execution 153 is terminated, an [`Error`][] will be thrown. **Default:** `false`. 154* Returns: {any} the result of the very last statement executed in the script. 155 156Runs the compiled code contained by the `vm.Script` object within the given 157`contextifiedObject` and returns the result. Running code does not have access 158to local scope. 159 160The following example compiles code that increments a global variable, sets 161the value of another global variable, then execute the code multiple times. 162The globals are contained in the `context` object. 163 164```js 165const vm = require('vm'); 166 167const context = { 168 animal: 'cat', 169 count: 2 170}; 171 172const script = new vm.Script('count += 1; name = "kitty";'); 173 174vm.createContext(context); 175for (let i = 0; i < 10; ++i) { 176 script.runInContext(context); 177} 178 179console.log(context); 180// Prints: { animal: 'cat', count: 12, name: 'kitty' } 181``` 182 183Using the `timeout` or `breakOnSigint` options will result in new event loops 184and corresponding threads being started, which have a non-zero performance 185overhead. 186 187### `script.runInNewContext([contextObject[, options]])` 188<!-- YAML 189added: v0.3.1 190changes: 191 - version: v10.0.0 192 pr-url: https://github.com/nodejs/node/pull/19016 193 description: The `contextCodeGeneration` option is supported now. 194 - version: v6.3.0 195 pr-url: https://github.com/nodejs/node/pull/6635 196 description: The `breakOnSigint` option is supported now. 197--> 198 199* `contextObject` {Object} An object that will be [contextified][]. If 200 `undefined`, a new object will be created. 201* `options` {Object} 202 * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs 203 while compiling the `code`, the line of code causing the error is attached 204 to the stack trace. **Default:** `true`. 205 * `timeout` {integer} Specifies the number of milliseconds to execute `code` 206 before terminating execution. If execution is terminated, an [`Error`][] 207 will be thrown. This value must be a strictly positive integer. 208 * `breakOnSigint` {boolean} If `true`, the execution will be terminated when 209 `SIGINT` (Ctrl+C) is received. Existing handlers for the 210 event that have been attached via `process.on('SIGINT')` will be disabled 211 during script execution, but will continue to work after that. If execution 212 is terminated, an [`Error`][] will be thrown. **Default:** `false`. 213 * `contextName` {string} Human-readable name of the newly created context. 214 **Default:** `'VM Context i'`, where `i` is an ascending numerical index of 215 the created context. 216 * `contextOrigin` {string} [Origin][origin] corresponding to the newly 217 created context for display purposes. The origin should be formatted like a 218 URL, but with only the scheme, host, and port (if necessary), like the 219 value of the [`url.origin`][] property of a [`URL`][] object. Most notably, 220 this string should omit the trailing slash, as that denotes a path. 221 **Default:** `''`. 222 * `contextCodeGeneration` {Object} 223 * `strings` {boolean} If set to false any calls to `eval` or function 224 constructors (`Function`, `GeneratorFunction`, etc) will throw an 225 `EvalError`. **Default:** `true`. 226 * `wasm` {boolean} If set to false any attempt to compile a WebAssembly 227 module will throw a `WebAssembly.CompileError`. **Default:** `true`. 228* Returns: {any} the result of the very last statement executed in the script. 229 230First contextifies the given `contextObject`, runs the compiled code contained 231by the `vm.Script` object within the created context, and returns the result. 232Running code does not have access to local scope. 233 234The following example compiles code that sets a global variable, then executes 235the code multiple times in different contexts. The globals are set on and 236contained within each individual `context`. 237 238```js 239const vm = require('vm'); 240 241const script = new vm.Script('globalVar = "set"'); 242 243const contexts = [{}, {}, {}]; 244contexts.forEach((context) => { 245 script.runInNewContext(context); 246}); 247 248console.log(contexts); 249// Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }] 250``` 251 252### `script.runInThisContext([options])` 253<!-- YAML 254added: v0.3.1 255changes: 256 - version: v6.3.0 257 pr-url: https://github.com/nodejs/node/pull/6635 258 description: The `breakOnSigint` option is supported now. 259--> 260 261* `options` {Object} 262 * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs 263 while compiling the `code`, the line of code causing the error is attached 264 to the stack trace. **Default:** `true`. 265 * `timeout` {integer} Specifies the number of milliseconds to execute `code` 266 before terminating execution. If execution is terminated, an [`Error`][] 267 will be thrown. This value must be a strictly positive integer. 268 * `breakOnSigint` {boolean} If `true`, the execution will be terminated when 269 `SIGINT` (Ctrl+C) is received. Existing handlers for the 270 event that have been attached via `process.on('SIGINT')` will be disabled 271 during script execution, but will continue to work after that. If execution 272 is terminated, an [`Error`][] will be thrown. **Default:** `false`. 273* Returns: {any} the result of the very last statement executed in the script. 274 275Runs the compiled code contained by the `vm.Script` within the context of the 276current `global` object. Running code does not have access to local scope, but 277*does* have access to the current `global` object. 278 279The following example compiles code that increments a `global` variable then 280executes that code multiple times: 281 282```js 283const vm = require('vm'); 284 285global.globalVar = 0; 286 287const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' }); 288 289for (let i = 0; i < 1000; ++i) { 290 script.runInThisContext(); 291} 292 293console.log(globalVar); 294 295// 1000 296``` 297 298## Class: `vm.Module` 299<!-- YAML 300added: v12.16.0 301--> 302 303> Stability: 1 - Experimental 304 305*This feature is only available with the `--experimental-vm-modules` command 306flag enabled.* 307 308The `vm.Module` class provides a low-level interface for using 309ECMAScript modules in VM contexts. It is the counterpart of the `vm.Script` 310class that closely mirrors [Module Record][]s as defined in the ECMAScript 311specification. 312 313Unlike `vm.Script` however, every `vm.Module` object is bound to a context from 314its creation. Operations on `vm.Module` objects are intrinsically asynchronous, 315in contrast with the synchronous nature of `vm.Script` objects. The use of 316'async' functions can help with manipulating `vm.Module` objects. 317 318Using a `vm.Module` object requires three distinct steps: creation/parsing, 319linking, and evaluation. These three steps are illustrated in the following 320example. 321 322This implementation lies at a lower level than the [ECMAScript Module 323loader][]. There is also no way to interact with the Loader yet, though 324support is planned. 325 326```js 327const vm = require('vm'); 328 329const contextifiedObject = vm.createContext({ secret: 42 }); 330 331(async () => { 332 // Step 1 333 // 334 // Create a Module by constructing a new `vm.SourceTextModule` object. This 335 // parses the provided source text, throwing a `SyntaxError` if anything goes 336 // wrong. By default, a Module is created in the top context. But here, we 337 // specify `contextifiedObject` as the context this Module belongs to. 338 // 339 // Here, we attempt to obtain the default export from the module "foo", and 340 // put it into local binding "secret". 341 342 const bar = new vm.SourceTextModule(` 343 import s from 'foo'; 344 s; 345 `, { context: contextifiedObject }); 346 347 // Step 2 348 // 349 // "Link" the imported dependencies of this Module to it. 350 // 351 // The provided linking callback (the "linker") accepts two arguments: the 352 // parent module (`bar` in this case) and the string that is the specifier of 353 // the imported module. The callback is expected to return a Module that 354 // corresponds to the provided specifier, with certain requirements documented 355 // in `module.link()`. 356 // 357 // If linking has not started for the returned Module, the same linker 358 // callback will be called on the returned Module. 359 // 360 // Even top-level Modules without dependencies must be explicitly linked. The 361 // callback provided would never be called, however. 362 // 363 // The link() method returns a Promise that will be resolved when all the 364 // Promises returned by the linker resolve. 365 // 366 // Note: This is a contrived example in that the linker function creates a new 367 // "foo" module every time it is called. In a full-fledged module system, a 368 // cache would probably be used to avoid duplicated modules. 369 370 async function linker(specifier, referencingModule) { 371 if (specifier === 'foo') { 372 return new vm.SourceTextModule(` 373 // The "secret" variable refers to the global variable we added to 374 // "contextifiedObject" when creating the context. 375 export default secret; 376 `, { context: referencingModule.context }); 377 378 // Using `contextifiedObject` instead of `referencingModule.context` 379 // here would work as well. 380 } 381 throw new Error(`Unable to resolve dependency: ${specifier}`); 382 } 383 await bar.link(linker); 384 385 // Step 3 386 // 387 // Evaluate the Module. The evaluate() method returns a Promise with a single 388 // property "result" that contains the result of the very last statement 389 // executed in the Module. In the case of `bar`, it is `s;`, which refers to 390 // the default export of the `foo` module, the `secret` we set in the 391 // beginning to 42. 392 393 const { result } = await bar.evaluate(); 394 395 console.log(result); 396 // Prints 42. 397})(); 398``` 399 400### `module.dependencySpecifiers` 401 402* {string[]} 403 404The specifiers of all dependencies of this module. The returned array is frozen 405to disallow any changes to it. 406 407Corresponds to the `[[RequestedModules]]` field of [Cyclic Module Record][]s in 408the ECMAScript specification. 409 410### `module.error` 411 412* {any} 413 414If the `module.status` is `'errored'`, this property contains the exception 415thrown by the module during evaluation. If the status is anything else, 416accessing this property will result in a thrown exception. 417 418The value `undefined` cannot be used for cases where there is not a thrown 419exception due to possible ambiguity with `throw undefined;`. 420 421Corresponds to the `[[EvaluationError]]` field of [Cyclic Module Record][]s 422in the ECMAScript specification. 423 424### `module.evaluate([options])` 425 426* `options` {Object} 427 * `timeout` {integer} Specifies the number of milliseconds to evaluate 428 before terminating execution. If execution is interrupted, an [`Error`][] 429 will be thrown. This value must be a strictly positive integer. 430 * `breakOnSigint` {boolean} If `true`, the execution will be terminated when 431 `SIGINT` (Ctrl+C) is received. Existing handlers for the event that have 432 been attached via `process.on('SIGINT')` will be disabled during script 433 execution, but will continue to work after that. If execution is 434 interrupted, an [`Error`][] will be thrown. **Default:** `false`. 435* Returns: {Promise} 436 437Evaluate the module. 438 439This must be called after the module has been linked; otherwise it will 440throw an error. It could be called also when the module has already been 441evaluated, in which case it will do one of the following two things: 442 443* return `undefined` if the initial evaluation ended in success (`module.status` 444 is `'evaluated'`) 445* rethrow the same exception the initial evaluation threw if the initial 446 evaluation ended in an error (`module.status` is `'errored'`) 447 448This method cannot be called while the module is being evaluated 449(`module.status` is `'evaluating'`) to prevent infinite recursion. 450 451Corresponds to the [Evaluate() concrete method][] field of [Cyclic Module 452Record][]s in the ECMAScript specification. 453 454### `module.link(linker)` 455 456* `linker` {Function} 457 * `specifier` {string} The specifier of the requested module: 458 <!-- eslint-skip --> 459 ```js 460 import foo from 'foo'; 461 // ^^^^^ the module specifier 462 ``` 463 464 * `referencingModule` {vm.Module} The `Module` object `link()` is called on. 465 * Returns: {vm.Module|Promise} 466* Returns: {Promise} 467 468Link module dependencies. This method must be called before evaluation, and 469can only be called once per module. 470 471The function is expected to return a `Module` object or a `Promise` that 472eventually resolves to a `Module` object. The returned `Module` must satisfy the 473following two invariants: 474 475* It must belong to the same context as the parent `Module`. 476* Its `status` must not be `'errored'`. 477 478If the returned `Module`'s `status` is `'unlinked'`, this method will be 479recursively called on the returned `Module` with the same provided `linker` 480function. 481 482`link()` returns a `Promise` that will either get resolved when all linking 483instances resolve to a valid `Module`, or rejected if the linker function either 484throws an exception or returns an invalid `Module`. 485 486The linker function roughly corresponds to the implementation-defined 487[HostResolveImportedModule][] abstract operation in the ECMAScript 488specification, with a few key differences: 489 490* The linker function is allowed to be asynchronous while 491 [HostResolveImportedModule][] is synchronous. 492 493The actual [HostResolveImportedModule][] implementation used during module 494linking is one that returns the modules linked during linking. Since at 495that point all modules would have been fully linked already, the 496[HostResolveImportedModule][] implementation is fully synchronous per 497specification. 498 499Corresponds to the [Link() concrete method][] field of [Cyclic Module 500Record][]s in the ECMAScript specification. 501 502### `module.namespace` 503 504* {Object} 505 506The namespace object of the module. This is only available after linking 507(`module.link()`) has completed. 508 509Corresponds to the [GetModuleNamespace][] abstract operation in the ECMAScript 510specification. 511 512### `module.status` 513 514* {string} 515 516The current status of the module. Will be one of: 517 518* `'unlinked'`: `module.link()` has not yet been called. 519 520* `'linking'`: `module.link()` has been called, but not all Promises returned 521 by the linker function have been resolved yet. 522 523* `'linked'`: The module has been linked successfully, and all of its 524 dependencies are linked, but `module.evaluate()` has not yet been called. 525 526* `'evaluating'`: The module is being evaluated through a `module.evaluate()` on 527 itself or a parent module. 528 529* `'evaluated'`: The module has been successfully evaluated. 530 531* `'errored'`: The module has been evaluated, but an exception was thrown. 532 533Other than `'errored'`, this status string corresponds to the specification's 534[Cyclic Module Record][]'s `[[Status]]` field. `'errored'` corresponds to 535`'evaluated'` in the specification, but with `[[EvaluationError]]` set to a 536value that is not `undefined`. 537 538### `module.identifier` 539 540* {string} 541 542The identifier of the current module, as set in the constructor. 543 544## Class: `vm.SourceTextModule` 545<!-- YAML 546added: v9.6.0 547--> 548 549> Stability: 1 - Experimental 550 551*This feature is only available with the `--experimental-vm-modules` command 552flag enabled.* 553 554* Extends: {vm.Module} 555 556The `vm.SourceTextModule` class provides the [Source Text Module Record][] as 557defined in the ECMAScript specification. 558 559### `new vm.SourceTextModule(code[, options])` 560 561* `code` {string} JavaScript Module code to parse 562* `options` 563 * `identifier` {string} String used in stack traces. 564 **Default:** `'vm:module(i)'` where `i` is a context-specific ascending 565 index. 566 * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or 567 `TypedArray`, or `DataView` with V8's code cache data for the supplied 568 source. The `code` must be the same as the module from which this 569 `cachedData` was created. 570 * `context` {Object} The [contextified][] object as returned by the 571 `vm.createContext()` method, to compile and evaluate this `Module` in. 572 * `lineOffset` {integer} Specifies the line number offset that is displayed 573 in stack traces produced by this `Module`. **Default:** `0`. 574 * `columnOffset` {integer} Specifies the column number offset that is 575 displayed in stack traces produced by this `Module`. **Default:** `0`. 576 * `initializeImportMeta` {Function} Called during evaluation of this `Module` 577 to initialize the `import.meta`. 578 * `meta` {import.meta} 579 * `module` {vm.SourceTextModule} 580 * `importModuleDynamically` {Function} Called during evaluation of this module 581 when `import()` is called. If this option is not specified, calls to 582 `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. 583 * `specifier` {string} specifier passed to `import()` 584 * `module` {vm.Module} 585 * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is 586 recommended in order to take advantage of error tracking, and to avoid 587 issues with namespaces that contain `then` function exports. 588 589Creates a new `SourceTextModule` instance. 590 591Properties assigned to the `import.meta` object that are objects may 592allow the module to access information outside the specified `context`. Use 593`vm.runInContext()` to create objects in a specific context. 594 595```js 596const vm = require('vm'); 597 598const contextifiedObject = vm.createContext({ secret: 42 }); 599 600(async () => { 601 const module = new vm.SourceTextModule( 602 'Object.getPrototypeOf(import.meta.prop).secret = secret;', 603 { 604 initializeImportMeta(meta) { 605 // Note: this object is created in the top context. As such, 606 // Object.getPrototypeOf(import.meta.prop) points to the 607 // Object.prototype in the top context rather than that in 608 // the contextified object. 609 meta.prop = {}; 610 } 611 }); 612 // Since module has no dependencies, the linker function will never be called. 613 await module.link(() => {}); 614 await module.evaluate(); 615 616 // Now, Object.prototype.secret will be equal to 42. 617 // 618 // To fix this problem, replace 619 // meta.prop = {}; 620 // above with 621 // meta.prop = vm.runInContext('{}', contextifiedObject); 622})(); 623``` 624 625### `sourceTextModule.createCachedData()` 626<!-- YAML 627added: v12.17.0 628--> 629 630* Returns: {Buffer} 631 632Creates a code cache that can be used with the SourceTextModule constructor's 633`cachedData` option. Returns a Buffer. This method may be called any number 634of times before the module has been evaluated. 635 636```js 637// Create an initial module 638const module = new vm.SourceTextModule('const a = 1;'); 639 640// Create cached data from this module 641const cachedData = module.createCachedData(); 642 643// Create a new module using the cached data. The code must be the same. 644const module2 = new vm.SourceTextModule('const a = 1;', { cachedData }); 645``` 646 647## Class: `vm.SyntheticModule` 648<!-- YAML 649added: v12.16.0 650--> 651 652> Stability: 1 - Experimental 653 654*This feature is only available with the `--experimental-vm-modules` command 655flag enabled.* 656 657* Extends: {vm.Module} 658 659The `vm.SyntheticModule` class provides the [Synthetic Module Record][] as 660defined in the WebIDL specification. The purpose of synthetic modules is to 661provide a generic interface for exposing non-JavaScript sources to ECMAScript 662module graphs. 663 664```js 665const vm = require('vm'); 666 667const source = '{ "a": 1 }'; 668const module = new vm.SyntheticModule(['default'], function() { 669 const obj = JSON.parse(source); 670 this.setExport('default', obj); 671}); 672 673// Use `module` in linking... 674``` 675 676### `new vm.SyntheticModule(exportNames, evaluateCallback[, options])` 677<!-- YAML 678added: v12.16.0 679--> 680 681* `exportNames` {string[]} Array of names that will be exported from the module. 682* `evaluateCallback` {Function} Called when the module is evaluated. 683* `options` 684 * `identifier` {string} String used in stack traces. 685 **Default:** `'vm:module(i)'` where `i` is a context-specific ascending 686 index. 687 * `context` {Object} The [contextified][] object as returned by the 688 `vm.createContext()` method, to compile and evaluate this `Module` in. 689 690Creates a new `SyntheticModule` instance. 691 692Objects assigned to the exports of this instance may allow importers of 693the module to access information outside the specified `context`. Use 694`vm.runInContext()` to create objects in a specific context. 695 696### `syntheticModule.setExport(name, value)` 697<!-- YAML 698added: v12.16.0 699--> 700 701* `name` {string} Name of the export to set. 702* `value` {any} The value to set the export to. 703 704This method is used after the module is linked to set the values of exports. If 705it is called before the module is linked, an [`ERR_VM_MODULE_STATUS`][] error 706will be thrown. 707 708```js 709const vm = require('vm'); 710 711(async () => { 712 const m = new vm.SyntheticModule(['x'], () => { 713 m.setExport('x', 1); 714 }); 715 716 await m.link(() => {}); 717 await m.evaluate(); 718 719 assert.strictEqual(m.namespace.x, 1); 720})(); 721``` 722 723## `vm.compileFunction(code[, params[, options]])` 724<!-- YAML 725added: v10.10.0 726--> 727 728* `code` {string} The body of the function to compile. 729* `params` {string[]} An array of strings containing all parameters for the 730 function. 731* `options` {Object} 732 * `filename` {string} Specifies the filename used in stack traces produced 733 by this script. **Default:** `''`. 734 * `lineOffset` {number} Specifies the line number offset that is displayed 735 in stack traces produced by this script. **Default:** `0`. 736 * `columnOffset` {number} Specifies the column number offset that is displayed 737 in stack traces produced by this script. **Default:** `0`. 738 * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or 739 `TypedArray`, or `DataView` with V8's code cache data for the supplied 740 source. 741 * `produceCachedData` {boolean} Specifies whether to produce new cache data. 742 **Default:** `false`. 743 * `parsingContext` {Object} The [contextified][] object in which the said 744 function should be compiled in. 745 * `contextExtensions` {Object[]} An array containing a collection of context 746 extensions (objects wrapping the current scope) to be applied while 747 compiling. **Default:** `[]`. 748* Returns: {Function} 749 750Compiles the given code into the provided context (if no context is 751supplied, the current context is used), and returns it wrapped inside a 752function with the given `params`. 753 754## `vm.createContext([contextObject[, options]])` 755<!-- YAML 756added: v0.3.1 757changes: 758 - version: v10.0.0 759 pr-url: https://github.com/nodejs/node/pull/19398 760 description: The first argument can no longer be a function. 761 - version: v10.0.0 762 pr-url: https://github.com/nodejs/node/pull/19016 763 description: The `codeGeneration` option is supported now. 764--> 765 766* `contextObject` {Object} 767* `options` {Object} 768 * `name` {string} Human-readable name of the newly created context. 769 **Default:** `'VM Context i'`, where `i` is an ascending numerical index of 770 the created context. 771 * `origin` {string} [Origin][origin] corresponding to the newly created 772 context for display purposes. The origin should be formatted like a URL, 773 but with only the scheme, host, and port (if necessary), like the value of 774 the [`url.origin`][] property of a [`URL`][] object. Most notably, this 775 string should omit the trailing slash, as that denotes a path. 776 **Default:** `''`. 777 * `codeGeneration` {Object} 778 * `strings` {boolean} If set to false any calls to `eval` or function 779 constructors (`Function`, `GeneratorFunction`, etc) will throw an 780 `EvalError`. **Default:** `true`. 781 * `wasm` {boolean} If set to false any attempt to compile a WebAssembly 782 module will throw a `WebAssembly.CompileError`. **Default:** `true`. 783* Returns: {Object} contextified object. 784 785If given a `contextObject`, the `vm.createContext()` method will [prepare 786that object][contextified] so that it can be used in calls to 787[`vm.runInContext()`][] or [`script.runInContext()`][]. Inside such scripts, 788the `contextObject` will be the global object, retaining all of its existing 789properties but also having the built-in objects and functions any standard 790[global object][] has. Outside of scripts run by the vm module, global variables 791will remain unchanged. 792 793```js 794const vm = require('vm'); 795 796global.globalVar = 3; 797 798const context = { globalVar: 1 }; 799vm.createContext(context); 800 801vm.runInContext('globalVar *= 2;', context); 802 803console.log(context); 804// Prints: { globalVar: 2 } 805 806console.log(global.globalVar); 807// Prints: 3 808``` 809 810If `contextObject` is omitted (or passed explicitly as `undefined`), a new, 811empty [contextified][] object will be returned. 812 813The `vm.createContext()` method is primarily useful for creating a single 814context that can be used to run multiple scripts. For instance, if emulating a 815web browser, the method can be used to create a single context representing a 816window's global object, then run all `<script>` tags together within that 817context. 818 819The provided `name` and `origin` of the context are made visible through the 820Inspector API. 821 822## `vm.isContext(object)` 823<!-- YAML 824added: v0.11.7 825--> 826 827* `object` {Object} 828* Returns: {boolean} 829 830Returns `true` if the given `oject` object has been [contextified][] using 831[`vm.createContext()`][]. 832 833## `vm.runInContext(code, contextifiedObject[, options])` 834<!-- YAML 835added: v0.3.1 836changes: 837 - version: v6.3.0 838 pr-url: https://github.com/nodejs/node/pull/6635 839 description: The `breakOnSigint` option is supported now. 840--> 841 842* `code` {string} The JavaScript code to compile and run. 843* `contextifiedObject` {Object} The [contextified][] object that will be used 844 as the `global` when the `code` is compiled and run. 845* `options` {Object|string} 846 * `filename` {string} Specifies the filename used in stack traces produced 847 by this script. **Default:** `'evalmachine.<anonymous>'`. 848 * `lineOffset` {number} Specifies the line number offset that is displayed 849 in stack traces produced by this script. **Default:** `0`. 850 * `columnOffset` {number} Specifies the column number offset that is displayed 851 in stack traces produced by this script. **Default:** `0`. 852 * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs 853 while compiling the `code`, the line of code causing the error is attached 854 to the stack trace. **Default:** `true`. 855 * `timeout` {integer} Specifies the number of milliseconds to execute `code` 856 before terminating execution. If execution is terminated, an [`Error`][] 857 will be thrown. This value must be a strictly positive integer. 858 * `breakOnSigint` {boolean} If `true`, the execution will be terminated when 859 `SIGINT` (Ctrl+C) is received. Existing handlers for the 860 event that have been attached via `process.on('SIGINT')` will be disabled 861 during script execution, but will continue to work after that. If execution 862 is terminated, an [`Error`][] will be thrown. **Default:** `false`. 863 * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or 864 `TypedArray`, or `DataView` with V8's code cache data for the supplied 865 source. When supplied, the `cachedDataRejected` value will be set to 866 either `true` or `false` depending on acceptance of the data by V8. 867 * `produceCachedData` {boolean} When `true` and no `cachedData` is present, V8 868 will attempt to produce code cache data for `code`. Upon success, a 869 `Buffer` with V8's code cache data will be produced and stored in the 870 `cachedData` property of the returned `vm.Script` instance. 871 The `cachedDataProduced` value will be set to either `true` or `false` 872 depending on whether code cache data is produced successfully. 873 This option is **deprecated** in favor of `script.createCachedData()`. 874 **Default:** `false`. 875 * `importModuleDynamically` {Function} Called during evaluation of this module 876 when `import()` is called. If this option is not specified, calls to 877 `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. 878 This option is part of the experimental modules API, and should not be 879 considered stable. 880 * `specifier` {string} specifier passed to `import()` 881 * `module` {vm.Module} 882 * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is 883 recommended in order to take advantage of error tracking, and to avoid 884 issues with namespaces that contain `then` function exports. 885* Returns: {any} the result of the very last statement executed in the script. 886 887The `vm.runInContext()` method compiles `code`, runs it within the context of 888the `contextifiedObject`, then returns the result. Running code does not have 889access to the local scope. The `contextifiedObject` object *must* have been 890previously [contextified][] using the [`vm.createContext()`][] method. 891 892If `options` is a string, then it specifies the filename. 893 894The following example compiles and executes different scripts using a single 895[contextified][] object: 896 897```js 898const vm = require('vm'); 899 900const contextObject = { globalVar: 1 }; 901vm.createContext(contextObject); 902 903for (let i = 0; i < 10; ++i) { 904 vm.runInContext('globalVar *= 2;', contextObject); 905} 906console.log(contextObject); 907// Prints: { globalVar: 1024 } 908``` 909 910## `vm.runInNewContext(code[, contextObject[, options]])` 911<!-- YAML 912added: v0.3.1 913changes: 914 - version: v10.0.0 915 pr-url: https://github.com/nodejs/node/pull/19016 916 description: The `contextCodeGeneration` option is supported now. 917 - version: v6.3.0 918 pr-url: https://github.com/nodejs/node/pull/6635 919 description: The `breakOnSigint` option is supported now. 920--> 921 922* `code` {string} The JavaScript code to compile and run. 923* `contextObject` {Object} An object that will be [contextified][]. If 924 `undefined`, a new object will be created. 925* `options` {Object|string} 926 * `filename` {string} Specifies the filename used in stack traces produced 927 by this script. **Default:** `'evalmachine.<anonymous>'`. 928 * `lineOffset` {number} Specifies the line number offset that is displayed 929 in stack traces produced by this script. **Default:** `0`. 930 * `columnOffset` {number} Specifies the column number offset that is displayed 931 in stack traces produced by this script. **Default:** `0`. 932 * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs 933 while compiling the `code`, the line of code causing the error is attached 934 to the stack trace. **Default:** `true`. 935 * `timeout` {integer} Specifies the number of milliseconds to execute `code` 936 before terminating execution. If execution is terminated, an [`Error`][] 937 will be thrown. This value must be a strictly positive integer. 938 * `breakOnSigint` {boolean} If `true`, the execution will be terminated when 939 `SIGINT` (Ctrl+C) is received. Existing handlers for the 940 event that have been attached via `process.on('SIGINT')` will be disabled 941 during script execution, but will continue to work after that. If execution 942 is terminated, an [`Error`][] will be thrown. **Default:** `false`. 943 * `contextName` {string} Human-readable name of the newly created context. 944 **Default:** `'VM Context i'`, where `i` is an ascending numerical index of 945 the created context. 946 * `contextOrigin` {string} [Origin][origin] corresponding to the newly 947 created context for display purposes. The origin should be formatted like a 948 URL, but with only the scheme, host, and port (if necessary), like the 949 value of the [`url.origin`][] property of a [`URL`][] object. Most notably, 950 this string should omit the trailing slash, as that denotes a path. 951 **Default:** `''`. 952 * `contextCodeGeneration` {Object} 953 * `strings` {boolean} If set to false any calls to `eval` or function 954 constructors (`Function`, `GeneratorFunction`, etc) will throw an 955 `EvalError`. **Default:** `true`. 956 * `wasm` {boolean} If set to false any attempt to compile a WebAssembly 957 module will throw a `WebAssembly.CompileError`. **Default:** `true`. 958 * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or 959 `TypedArray`, or `DataView` with V8's code cache data for the supplied 960 source. When supplied, the `cachedDataRejected` value will be set to 961 either `true` or `false` depending on acceptance of the data by V8. 962 * `produceCachedData` {boolean} When `true` and no `cachedData` is present, V8 963 will attempt to produce code cache data for `code`. Upon success, a 964 `Buffer` with V8's code cache data will be produced and stored in the 965 `cachedData` property of the returned `vm.Script` instance. 966 The `cachedDataProduced` value will be set to either `true` or `false` 967 depending on whether code cache data is produced successfully. 968 This option is **deprecated** in favor of `script.createCachedData()`. 969 **Default:** `false`. 970 * `importModuleDynamically` {Function} Called during evaluation of this module 971 when `import()` is called. If this option is not specified, calls to 972 `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. 973 This option is part of the experimental modules API, and should not be 974 considered stable. 975 * `specifier` {string} specifier passed to `import()` 976 * `module` {vm.Module} 977 * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is 978 recommended in order to take advantage of error tracking, and to avoid 979 issues with namespaces that contain `then` function exports. 980* Returns: {any} the result of the very last statement executed in the script. 981 982The `vm.runInNewContext()` first contextifies the given `contextObject` (or 983creates a new `contextObject` if passed as `undefined`), compiles the `code`, 984runs it within the created context, then returns the result. Running code 985does not have access to the local scope. 986 987If `options` is a string, then it specifies the filename. 988 989The following example compiles and executes code that increments a global 990variable and sets a new one. These globals are contained in the `contextObject`. 991 992```js 993const vm = require('vm'); 994 995const contextObject = { 996 animal: 'cat', 997 count: 2 998}; 999 1000vm.runInNewContext('count += 1; name = "kitty"', contextObject); 1001console.log(contextObject); 1002// Prints: { animal: 'cat', count: 3, name: 'kitty' } 1003``` 1004 1005## `vm.runInThisContext(code[, options])` 1006<!-- YAML 1007added: v0.3.1 1008changes: 1009 - version: v6.3.0 1010 pr-url: https://github.com/nodejs/node/pull/6635 1011 description: The `breakOnSigint` option is supported now. 1012--> 1013 1014* `code` {string} The JavaScript code to compile and run. 1015* `options` {Object|string} 1016 * `filename` {string} Specifies the filename used in stack traces produced 1017 by this script. **Default:** `'evalmachine.<anonymous>'`. 1018 * `lineOffset` {number} Specifies the line number offset that is displayed 1019 in stack traces produced by this script. **Default:** `0`. 1020 * `columnOffset` {number} Specifies the column number offset that is displayed 1021 in stack traces produced by this script. **Default:** `0`. 1022 * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs 1023 while compiling the `code`, the line of code causing the error is attached 1024 to the stack trace. **Default:** `true`. 1025 * `timeout` {integer} Specifies the number of milliseconds to execute `code` 1026 before terminating execution. If execution is terminated, an [`Error`][] 1027 will be thrown. This value must be a strictly positive integer. 1028 * `breakOnSigint` {boolean} If `true`, the execution will be terminated when 1029 `SIGINT` (Ctrl+C) is received. Existing handlers for the 1030 event that have been attached via `process.on('SIGINT')` will be disabled 1031 during script execution, but will continue to work after that. If execution 1032 is terminated, an [`Error`][] will be thrown. **Default:** `false`. 1033 * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or 1034 `TypedArray`, or `DataView` with V8's code cache data for the supplied 1035 source. When supplied, the `cachedDataRejected` value will be set to 1036 either `true` or `false` depending on acceptance of the data by V8. 1037 * `produceCachedData` {boolean} When `true` and no `cachedData` is present, V8 1038 will attempt to produce code cache data for `code`. Upon success, a 1039 `Buffer` with V8's code cache data will be produced and stored in the 1040 `cachedData` property of the returned `vm.Script` instance. 1041 The `cachedDataProduced` value will be set to either `true` or `false` 1042 depending on whether code cache data is produced successfully. 1043 This option is **deprecated** in favor of `script.createCachedData()`. 1044 **Default:** `false`. 1045 * `importModuleDynamically` {Function} Called during evaluation of this module 1046 when `import()` is called. If this option is not specified, calls to 1047 `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. 1048 This option is part of the experimental modules API, and should not be 1049 considered stable. 1050 * `specifier` {string} specifier passed to `import()` 1051 * `module` {vm.Module} 1052 * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is 1053 recommended in order to take advantage of error tracking, and to avoid 1054 issues with namespaces that contain `then` function exports. 1055* Returns: {any} the result of the very last statement executed in the script. 1056 1057`vm.runInThisContext()` compiles `code`, runs it within the context of the 1058current `global` and returns the result. Running code does not have access to 1059local scope, but does have access to the current `global` object. 1060 1061If `options` is a string, then it specifies the filename. 1062 1063The following example illustrates using both `vm.runInThisContext()` and 1064the JavaScript [`eval()`][] function to run the same code: 1065 1066<!-- eslint-disable prefer-const --> 1067```js 1068const vm = require('vm'); 1069let localVar = 'initial value'; 1070 1071const vmResult = vm.runInThisContext('localVar = "vm";'); 1072console.log(`vmResult: '${vmResult}', localVar: '${localVar}'`); 1073// Prints: vmResult: 'vm', localVar: 'initial value' 1074 1075const evalResult = eval('localVar = "eval";'); 1076console.log(`evalResult: '${evalResult}', localVar: '${localVar}'`); 1077// Prints: evalResult: 'eval', localVar: 'eval' 1078``` 1079 1080Because `vm.runInThisContext()` does not have access to the local scope, 1081`localVar` is unchanged. In contrast, [`eval()`][] *does* have access to the 1082local scope, so the value `localVar` is changed. In this way 1083`vm.runInThisContext()` is much like an [indirect `eval()` call][], e.g. 1084`(0,eval)('code')`. 1085 1086## Example: Running an HTTP server within a VM 1087 1088When using either [`script.runInThisContext()`][] or 1089[`vm.runInThisContext()`][], the code is executed within the current V8 global 1090context. The code passed to this VM context will have its own isolated scope. 1091 1092In order to run a simple web server using the `http` module the code passed to 1093the context must either call `require('http')` on its own, or have a reference 1094to the `http` module passed to it. For instance: 1095 1096```js 1097'use strict'; 1098const vm = require('vm'); 1099 1100const code = ` 1101((require) => { 1102 const http = require('http'); 1103 1104 http.createServer((request, response) => { 1105 response.writeHead(200, { 'Content-Type': 'text/plain' }); 1106 response.end('Hello World\\n'); 1107 }).listen(8124); 1108 1109 console.log('Server running at http://127.0.0.1:8124/'); 1110})`; 1111 1112vm.runInThisContext(code)(require); 1113``` 1114 1115The `require()` in the above case shares the state with the context it is 1116passed from. This may introduce risks when untrusted code is executed, e.g. 1117altering objects in the context in unwanted ways. 1118 1119## What does it mean to "contextify" an object? 1120 1121All JavaScript executed within Node.js runs within the scope of a "context". 1122According to the [V8 Embedder's Guide][]: 1123 1124> In V8, a context is an execution environment that allows separate, unrelated, 1125> JavaScript applications to run in a single instance of V8. You must explicitly 1126> specify the context in which you want any JavaScript code to be run. 1127 1128When the method `vm.createContext()` is called, the `contextObject` argument 1129(or a newly-created object if `contextObject` is `undefined`) is associated 1130internally with a new instance of a V8 Context. This V8 Context provides the 1131`code` run using the `vm` module's methods with an isolated global environment 1132within which it can operate. The process of creating the V8 Context and 1133associating it with the `contextObject` is what this document refers to as 1134"contextifying" the object. 1135 1136## Timeout limitations when using `process.nextTick()`, promises, and `queueMicrotask()` 1137 1138Because of the internal mechanics of how the `process.nextTick()` queue and 1139the microtask queue that underlies Promises are implemented within V8 and 1140Node.js, it is possible for code running within a context to "escape" the 1141`timeout` set using `vm.runInContext()`, `vm.runInNewContext()`, and 1142`vm.runInThisContext()`. 1143 1144For example, the following code executed by `vm.runInNewContext()` with a 1145timeout of 5 milliseconds schedules an infinite loop to run after a promise 1146resolves. The scheduled loop is never interrupted by the timeout: 1147 1148```js 1149const vm = require('vm'); 1150 1151function loop() { 1152 while (1) console.log(Date.now()); 1153} 1154 1155vm.runInNewContext( 1156 'Promise.resolve().then(loop);', 1157 { loop, console }, 1158 { timeout: 5 } 1159); 1160``` 1161 1162This issue also occurs when the `loop()` call is scheduled using 1163the `process.nextTick()` and `queueMicrotask()` functions. 1164 1165This issue occurs because all contexts share the same microtask and nextTick 1166queues. 1167 1168[`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`]: errors.html#ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING 1169[`ERR_VM_MODULE_STATUS`]: errors.html#ERR_VM_MODULE_STATUS 1170[`Error`]: errors.html#errors_class_error 1171[`URL`]: url.html#url_class_url 1172[`eval()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval 1173[`script.runInContext()`]: #vm_script_runincontext_contextifiedobject_options 1174[`script.runInThisContext()`]: #vm_script_runinthiscontext_options 1175[`url.origin`]: url.html#url_url_origin 1176[`vm.createContext()`]: #vm_vm_createcontext_contextobject_options 1177[`vm.runInContext()`]: #vm_vm_runincontext_code_contextifiedobject_options 1178[`vm.runInThisContext()`]: #vm_vm_runinthiscontext_code_options 1179[Cyclic Module Record]: https://tc39.es/ecma262/#sec-cyclic-module-records 1180[ECMAScript Module Loader]: esm.html#esm_modules_ecmascript_modules 1181[Evaluate() concrete method]: https://tc39.es/ecma262/#sec-moduleevaluation 1182[GetModuleNamespace]: https://tc39.es/ecma262/#sec-getmodulenamespace 1183[HostResolveImportedModule]: https://tc39.es/ecma262/#sec-hostresolveimportedmodule 1184[Link() concrete method]: https://tc39.es/ecma262/#sec-moduledeclarationlinking 1185[Module Record]: https://www.ecma-international.org/ecma-262/#sec-abstract-module-records 1186[Source Text Module Record]: https://tc39.es/ecma262/#sec-source-text-module-records 1187[Synthetic Module Record]: https://heycam.github.io/webidl/#synthetic-module-records 1188[V8 Embedder's Guide]: https://v8.dev/docs/embed#contexts 1189[contextified]: #vm_what_does_it_mean_to_contextify_an_object 1190[global object]: https://es5.github.io/#x15.1 1191[indirect `eval()` call]: https://es5.github.io/#x10.4.2 1192[origin]: https://developer.mozilla.org/en-US/docs/Glossary/Origin 1193