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 `node:vm` module enables compiling and running code within V8 Virtual 12Machine contexts. 13 14<strong class="critical">The `node:vm` module is not a security 15mechanism. Do not use it to run untrusted code.</strong> 16 17JavaScript code can be compiled and run immediately or 18compiled, saved, and run later. 19 20A common use case is to run the code in a different V8 Context. This means 21invoked code has a different global object than the invoking code. 22 23One can provide the context by [_contextifying_][contextified] an 24object. The invoked code treats any property in the context like a 25global variable. Any changes to global variables caused by the invoked 26code are reflected in the context object. 27 28```js 29const vm = require('node:vm'); 30 31const x = 1; 32 33const context = { x: 2 }; 34vm.createContext(context); // Contextify the object. 35 36const code = 'x += 40; var y = 17;'; 37// `x` and `y` are global variables in the context. 38// Initially, x has the value 2 because that is the value of context.x. 39vm.runInContext(code, context); 40 41console.log(context.x); // 42 42console.log(context.y); // 17 43 44console.log(x); // 1; y is not defined. 45``` 46 47## Class: `vm.Script` 48 49<!-- YAML 50added: v0.3.1 51--> 52 53Instances of the `vm.Script` class contain precompiled scripts that can be 54executed in specific contexts. 55 56### `new vm.Script(code[, options])` 57 58<!-- YAML 59added: v0.3.1 60changes: 61 - version: 62 - v17.0.0 63 - v16.12.0 64 pr-url: https://github.com/nodejs/node/pull/40249 65 description: Added support for import assertions to the 66 `importModuleDynamically` parameter. 67 - version: v10.6.0 68 pr-url: https://github.com/nodejs/node/pull/20300 69 description: The `produceCachedData` is deprecated in favour of 70 `script.createCachedData()`. 71 - version: v5.7.0 72 pr-url: https://github.com/nodejs/node/pull/4777 73 description: The `cachedData` and `produceCachedData` options are 74 supported now. 75--> 76 77* `code` {string} The JavaScript code to compile. 78* `options` {Object|string} 79 * `filename` {string} Specifies the filename used in stack traces produced 80 by this script. **Default:** `'evalmachine.<anonymous>'`. 81 * `lineOffset` {number} Specifies the line number offset that is displayed 82 in stack traces produced by this script. **Default:** `0`. 83 * `columnOffset` {number} Specifies the first-line column number offset that 84 is displayed in stack traces produced by this script. **Default:** `0`. 85 * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or 86 `TypedArray`, or `DataView` with V8's code cache data for the supplied 87 source. When supplied, the `cachedDataRejected` value will be set to 88 either `true` or `false` depending on acceptance of the data by V8. 89 * `produceCachedData` {boolean} When `true` and no `cachedData` is present, V8 90 will attempt to produce code cache data for `code`. Upon success, a 91 `Buffer` with V8's code cache data will be produced and stored in the 92 `cachedData` property of the returned `vm.Script` instance. 93 The `cachedDataProduced` value will be set to either `true` or `false` 94 depending on whether code cache data is produced successfully. 95 This option is **deprecated** in favor of `script.createCachedData()`. 96 **Default:** `false`. 97 * `importModuleDynamically` {Function} Called during evaluation of this module 98 when `import()` is called. If this option is not specified, calls to 99 `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. 100 This option is part of the experimental modules API. We do not recommend 101 using it in a production environment. 102 * `specifier` {string} specifier passed to `import()` 103 * `script` {vm.Script} 104 * `importAssertions` {Object} The `"assert"` value passed to the 105 [`optionsExpression`][] optional parameter, or an empty object if no value 106 was provided. 107 * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is 108 recommended in order to take advantage of error tracking, and to avoid 109 issues with namespaces that contain `then` function exports. 110 111If `options` is a string, then it specifies the filename. 112 113Creating a new `vm.Script` object compiles `code` but does not run it. The 114compiled `vm.Script` can be run later multiple times. The `code` is not bound to 115any global object; rather, it is bound before each run, just for that run. 116 117### `script.cachedDataRejected` 118 119<!-- YAML 120added: v5.7.0 121--> 122 123* {boolean|undefined} 124 125When `cachedData` is supplied to create the `vm.Script`, this value will be set 126to either `true` or `false` depending on acceptance of the data by V8. 127Otherwise the value is `undefined`. 128 129### `script.createCachedData()` 130 131<!-- YAML 132added: v10.6.0 133--> 134 135* Returns: {Buffer} 136 137Creates a code cache that can be used with the `Script` constructor's 138`cachedData` option. Returns a `Buffer`. This method may be called at any 139time and any number of times. 140 141The code cache of the `Script` doesn't contain any JavaScript observable 142states. The code cache is safe to be saved along side the script source and 143used to construct new `Script` instances multiple times. 144 145Functions in the `Script` source can be marked as lazily compiled and they are 146not compiled at construction of the `Script`. These functions are going to be 147compiled when they are invoked the first time. The code cache serializes the 148metadata that V8 currently knows about the `Script` that it can use to speed up 149future compilations. 150 151```js 152const script = new vm.Script(` 153function add(a, b) { 154 return a + b; 155} 156 157const x = add(1, 2); 158`); 159 160const cacheWithoutAdd = script.createCachedData(); 161// In `cacheWithoutAdd` the function `add()` is marked for full compilation 162// upon invocation. 163 164script.runInThisContext(); 165 166const cacheWithAdd = script.createCachedData(); 167// `cacheWithAdd` contains fully compiled function `add()`. 168``` 169 170### `script.runInContext(contextifiedObject[, options])` 171 172<!-- YAML 173added: v0.3.1 174changes: 175 - version: v6.3.0 176 pr-url: https://github.com/nodejs/node/pull/6635 177 description: The `breakOnSigint` option is supported now. 178--> 179 180* `contextifiedObject` {Object} A [contextified][] object as returned by the 181 `vm.createContext()` method. 182* `options` {Object} 183 * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs 184 while compiling the `code`, the line of code causing the error is attached 185 to the stack trace. **Default:** `true`. 186 * `timeout` {integer} Specifies the number of milliseconds to execute `code` 187 before terminating execution. If execution is terminated, an [`Error`][] 188 will be thrown. This value must be a strictly positive integer. 189 * `breakOnSigint` {boolean} If `true`, receiving `SIGINT` 190 (<kbd>Ctrl</kbd>+<kbd>C</kbd>) will terminate execution and throw an 191 [`Error`][]. Existing handlers for the event that have been attached via 192 `process.on('SIGINT')` are disabled during script execution, but continue to 193 work after that. **Default:** `false`. 194* Returns: {any} the result of the very last statement executed in the script. 195 196Runs the compiled code contained by the `vm.Script` object within the given 197`contextifiedObject` and returns the result. Running code does not have access 198to local scope. 199 200The following example compiles code that increments a global variable, sets 201the value of another global variable, then execute the code multiple times. 202The globals are contained in the `context` object. 203 204```js 205const vm = require('node:vm'); 206 207const context = { 208 animal: 'cat', 209 count: 2, 210}; 211 212const script = new vm.Script('count += 1; name = "kitty";'); 213 214vm.createContext(context); 215for (let i = 0; i < 10; ++i) { 216 script.runInContext(context); 217} 218 219console.log(context); 220// Prints: { animal: 'cat', count: 12, name: 'kitty' } 221``` 222 223Using the `timeout` or `breakOnSigint` options will result in new event loops 224and corresponding threads being started, which have a non-zero performance 225overhead. 226 227### `script.runInNewContext([contextObject[, options]])` 228 229<!-- YAML 230added: v0.3.1 231changes: 232 - version: v14.6.0 233 pr-url: https://github.com/nodejs/node/pull/34023 234 description: The `microtaskMode` option is supported now. 235 - version: v10.0.0 236 pr-url: https://github.com/nodejs/node/pull/19016 237 description: The `contextCodeGeneration` option is supported now. 238 - version: v6.3.0 239 pr-url: https://github.com/nodejs/node/pull/6635 240 description: The `breakOnSigint` option is supported now. 241--> 242 243* `contextObject` {Object} An object that will be [contextified][]. If 244 `undefined`, a new object will be created. 245* `options` {Object} 246 * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs 247 while compiling the `code`, the line of code causing the error is attached 248 to the stack trace. **Default:** `true`. 249 * `timeout` {integer} Specifies the number of milliseconds to execute `code` 250 before terminating execution. If execution is terminated, an [`Error`][] 251 will be thrown. This value must be a strictly positive integer. 252 * `breakOnSigint` {boolean} If `true`, receiving `SIGINT` 253 (<kbd>Ctrl</kbd>+<kbd>C</kbd>) will terminate execution and throw an 254 [`Error`][]. Existing handlers for the event that have been attached via 255 `process.on('SIGINT')` are disabled during script execution, but continue to 256 work after that. **Default:** `false`. 257 * `contextName` {string} Human-readable name of the newly created context. 258 **Default:** `'VM Context i'`, where `i` is an ascending numerical index of 259 the created context. 260 * `contextOrigin` {string} [Origin][origin] corresponding to the newly 261 created context for display purposes. The origin should be formatted like a 262 URL, but with only the scheme, host, and port (if necessary), like the 263 value of the [`url.origin`][] property of a [`URL`][] object. Most notably, 264 this string should omit the trailing slash, as that denotes a path. 265 **Default:** `''`. 266 * `contextCodeGeneration` {Object} 267 * `strings` {boolean} If set to false any calls to `eval` or function 268 constructors (`Function`, `GeneratorFunction`, etc) will throw an 269 `EvalError`. **Default:** `true`. 270 * `wasm` {boolean} If set to false any attempt to compile a WebAssembly 271 module will throw a `WebAssembly.CompileError`. **Default:** `true`. 272 * `microtaskMode` {string} If set to `afterEvaluate`, microtasks (tasks 273 scheduled through `Promise`s and `async function`s) will be run immediately 274 after the script has run. They are included in the `timeout` and 275 `breakOnSigint` scopes in that case. 276* Returns: {any} the result of the very last statement executed in the script. 277 278First contextifies the given `contextObject`, runs the compiled code contained 279by the `vm.Script` object within the created context, and returns the result. 280Running code does not have access to local scope. 281 282The following example compiles code that sets a global variable, then executes 283the code multiple times in different contexts. The globals are set on and 284contained within each individual `context`. 285 286```js 287const vm = require('node:vm'); 288 289const script = new vm.Script('globalVar = "set"'); 290 291const contexts = [{}, {}, {}]; 292contexts.forEach((context) => { 293 script.runInNewContext(context); 294}); 295 296console.log(contexts); 297// Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }] 298``` 299 300### `script.runInThisContext([options])` 301 302<!-- YAML 303added: v0.3.1 304changes: 305 - version: v6.3.0 306 pr-url: https://github.com/nodejs/node/pull/6635 307 description: The `breakOnSigint` option is supported now. 308--> 309 310* `options` {Object} 311 * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs 312 while compiling the `code`, the line of code causing the error is attached 313 to the stack trace. **Default:** `true`. 314 * `timeout` {integer} Specifies the number of milliseconds to execute `code` 315 before terminating execution. If execution is terminated, an [`Error`][] 316 will be thrown. This value must be a strictly positive integer. 317 * `breakOnSigint` {boolean} If `true`, receiving `SIGINT` 318 (<kbd>Ctrl</kbd>+<kbd>C</kbd>) will terminate execution and throw an 319 [`Error`][]. Existing handlers for the event that have been attached via 320 `process.on('SIGINT')` are disabled during script execution, but continue to 321 work after that. **Default:** `false`. 322* Returns: {any} the result of the very last statement executed in the script. 323 324Runs the compiled code contained by the `vm.Script` within the context of the 325current `global` object. Running code does not have access to local scope, but 326_does_ have access to the current `global` object. 327 328The following example compiles code that increments a `global` variable then 329executes that code multiple times: 330 331```js 332const vm = require('node:vm'); 333 334global.globalVar = 0; 335 336const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' }); 337 338for (let i = 0; i < 1000; ++i) { 339 script.runInThisContext(); 340} 341 342console.log(globalVar); 343 344// 1000 345``` 346 347### `script.sourceMapURL` 348 349<!-- YAML 350added: v18.13.0 351--> 352 353* {string|undefined} 354 355When the script is compiled from a source that contains a source map magic 356comment, this property will be set to the URL of the source map. 357 358```mjs 359import vm from 'node:vm'; 360 361const script = new vm.Script(` 362function myFunc() {} 363//# sourceMappingURL=sourcemap.json 364`); 365 366console.log(script.sourceMapURL); 367// Prints: sourcemap.json 368``` 369 370```cjs 371const vm = require('node:vm'); 372 373const script = new vm.Script(` 374function myFunc() {} 375//# sourceMappingURL=sourcemap.json 376`); 377 378console.log(script.sourceMapURL); 379// Prints: sourcemap.json 380``` 381 382## Class: `vm.Module` 383 384<!-- YAML 385added: 386 - v13.0.0 387 - v12.16.0 388--> 389 390> Stability: 1 - Experimental 391 392This feature is only available with the `--experimental-vm-modules` command 393flag enabled. 394 395The `vm.Module` class provides a low-level interface for using 396ECMAScript modules in VM contexts. It is the counterpart of the `vm.Script` 397class that closely mirrors [Module Record][]s as defined in the ECMAScript 398specification. 399 400Unlike `vm.Script` however, every `vm.Module` object is bound to a context from 401its creation. Operations on `vm.Module` objects are intrinsically asynchronous, 402in contrast with the synchronous nature of `vm.Script` objects. The use of 403'async' functions can help with manipulating `vm.Module` objects. 404 405Using a `vm.Module` object requires three distinct steps: creation/parsing, 406linking, and evaluation. These three steps are illustrated in the following 407example. 408 409This implementation lies at a lower level than the [ECMAScript Module 410loader][]. There is also no way to interact with the Loader yet, though 411support is planned. 412 413```mjs 414import vm from 'node:vm'; 415 416const contextifiedObject = vm.createContext({ 417 secret: 42, 418 print: console.log, 419}); 420 421// Step 1 422// 423// Create a Module by constructing a new `vm.SourceTextModule` object. This 424// parses the provided source text, throwing a `SyntaxError` if anything goes 425// wrong. By default, a Module is created in the top context. But here, we 426// specify `contextifiedObject` as the context this Module belongs to. 427// 428// Here, we attempt to obtain the default export from the module "foo", and 429// put it into local binding "secret". 430 431const bar = new vm.SourceTextModule(` 432 import s from 'foo'; 433 s; 434 print(s); 435`, { context: contextifiedObject }); 436 437// Step 2 438// 439// "Link" the imported dependencies of this Module to it. 440// 441// The provided linking callback (the "linker") accepts two arguments: the 442// parent module (`bar` in this case) and the string that is the specifier of 443// the imported module. The callback is expected to return a Module that 444// corresponds to the provided specifier, with certain requirements documented 445// in `module.link()`. 446// 447// If linking has not started for the returned Module, the same linker 448// callback will be called on the returned Module. 449// 450// Even top-level Modules without dependencies must be explicitly linked. The 451// callback provided would never be called, however. 452// 453// The link() method returns a Promise that will be resolved when all the 454// Promises returned by the linker resolve. 455// 456// Note: This is a contrived example in that the linker function creates a new 457// "foo" module every time it is called. In a full-fledged module system, a 458// cache would probably be used to avoid duplicated modules. 459 460async function linker(specifier, referencingModule) { 461 if (specifier === 'foo') { 462 return new vm.SourceTextModule(` 463 // The "secret" variable refers to the global variable we added to 464 // "contextifiedObject" when creating the context. 465 export default secret; 466 `, { context: referencingModule.context }); 467 468 // Using `contextifiedObject` instead of `referencingModule.context` 469 // here would work as well. 470 } 471 throw new Error(`Unable to resolve dependency: ${specifier}`); 472} 473await bar.link(linker); 474 475// Step 3 476// 477// Evaluate the Module. The evaluate() method returns a promise which will 478// resolve after the module has finished evaluating. 479 480// Prints 42. 481await bar.evaluate(); 482``` 483 484```cjs 485const vm = require('node:vm'); 486 487const contextifiedObject = vm.createContext({ 488 secret: 42, 489 print: console.log, 490}); 491 492(async () => { 493 // Step 1 494 // 495 // Create a Module by constructing a new `vm.SourceTextModule` object. This 496 // parses the provided source text, throwing a `SyntaxError` if anything goes 497 // wrong. By default, a Module is created in the top context. But here, we 498 // specify `contextifiedObject` as the context this Module belongs to. 499 // 500 // Here, we attempt to obtain the default export from the module "foo", and 501 // put it into local binding "secret". 502 503 const bar = new vm.SourceTextModule(` 504 import s from 'foo'; 505 s; 506 print(s); 507 `, { context: contextifiedObject }); 508 509 // Step 2 510 // 511 // "Link" the imported dependencies of this Module to it. 512 // 513 // The provided linking callback (the "linker") accepts two arguments: the 514 // parent module (`bar` in this case) and the string that is the specifier of 515 // the imported module. The callback is expected to return a Module that 516 // corresponds to the provided specifier, with certain requirements documented 517 // in `module.link()`. 518 // 519 // If linking has not started for the returned Module, the same linker 520 // callback will be called on the returned Module. 521 // 522 // Even top-level Modules without dependencies must be explicitly linked. The 523 // callback provided would never be called, however. 524 // 525 // The link() method returns a Promise that will be resolved when all the 526 // Promises returned by the linker resolve. 527 // 528 // Note: This is a contrived example in that the linker function creates a new 529 // "foo" module every time it is called. In a full-fledged module system, a 530 // cache would probably be used to avoid duplicated modules. 531 532 async function linker(specifier, referencingModule) { 533 if (specifier === 'foo') { 534 return new vm.SourceTextModule(` 535 // The "secret" variable refers to the global variable we added to 536 // "contextifiedObject" when creating the context. 537 export default secret; 538 `, { context: referencingModule.context }); 539 540 // Using `contextifiedObject` instead of `referencingModule.context` 541 // here would work as well. 542 } 543 throw new Error(`Unable to resolve dependency: ${specifier}`); 544 } 545 await bar.link(linker); 546 547 // Step 3 548 // 549 // Evaluate the Module. The evaluate() method returns a promise which will 550 // resolve after the module has finished evaluating. 551 552 // Prints 42. 553 await bar.evaluate(); 554})(); 555``` 556 557### `module.dependencySpecifiers` 558 559* {string\[]} 560 561The specifiers of all dependencies of this module. The returned array is frozen 562to disallow any changes to it. 563 564Corresponds to the `[[RequestedModules]]` field of [Cyclic Module Record][]s in 565the ECMAScript specification. 566 567### `module.error` 568 569* {any} 570 571If the `module.status` is `'errored'`, this property contains the exception 572thrown by the module during evaluation. If the status is anything else, 573accessing this property will result in a thrown exception. 574 575The value `undefined` cannot be used for cases where there is not a thrown 576exception due to possible ambiguity with `throw undefined;`. 577 578Corresponds to the `[[EvaluationError]]` field of [Cyclic Module Record][]s 579in the ECMAScript specification. 580 581### `module.evaluate([options])` 582 583* `options` {Object} 584 * `timeout` {integer} Specifies the number of milliseconds to evaluate 585 before terminating execution. If execution is interrupted, an [`Error`][] 586 will be thrown. This value must be a strictly positive integer. 587 * `breakOnSigint` {boolean} If `true`, receiving `SIGINT` 588 (<kbd>Ctrl</kbd>+<kbd>C</kbd>) will terminate execution and throw an 589 [`Error`][]. Existing handlers for the event that have been attached via 590 `process.on('SIGINT')` are disabled during script execution, but continue to 591 work after that. **Default:** `false`. 592* Returns: {Promise} Fulfills with `undefined` upon success. 593 594Evaluate the module. 595 596This must be called after the module has been linked; otherwise it will reject. 597It could be called also when the module has already been evaluated, in which 598case it will either do nothing if the initial evaluation ended in success 599(`module.status` is `'evaluated'`) or it will re-throw the exception that the 600initial evaluation resulted in (`module.status` is `'errored'`). 601 602This method cannot be called while the module is being evaluated 603(`module.status` is `'evaluating'`). 604 605Corresponds to the [Evaluate() concrete method][] field of [Cyclic Module 606Record][]s in the ECMAScript specification. 607 608### `module.identifier` 609 610* {string} 611 612The identifier of the current module, as set in the constructor. 613 614### `module.link(linker)` 615 616* `linker` {Function} 617 * `specifier` {string} The specifier of the requested module: 618 ```mjs 619 import foo from 'foo'; 620 // ^^^^^ the module specifier 621 ``` 622 623 * `referencingModule` {vm.Module} The `Module` object `link()` is called on. 624 625 * `extra` {Object} 626 * `assert` {Object} The data from the assertion: 627 <!-- eslint-skip --> 628 ```js 629 import foo from 'foo' assert { name: 'value' }; 630 // ^^^^^^^^^^^^^^^^^ the assertion 631 ``` 632 Per ECMA-262, hosts are expected to ignore assertions that they do not 633 support, as opposed to, for example, triggering an error if an 634 unsupported assertion is present. 635 636 * Returns: {vm.Module|Promise} 637* Returns: {Promise} 638 639Link module dependencies. This method must be called before evaluation, and 640can only be called once per module. 641 642The function is expected to return a `Module` object or a `Promise` that 643eventually resolves to a `Module` object. The returned `Module` must satisfy the 644following two invariants: 645 646* It must belong to the same context as the parent `Module`. 647* Its `status` must not be `'errored'`. 648 649If the returned `Module`'s `status` is `'unlinked'`, this method will be 650recursively called on the returned `Module` with the same provided `linker` 651function. 652 653`link()` returns a `Promise` that will either get resolved when all linking 654instances resolve to a valid `Module`, or rejected if the linker function either 655throws an exception or returns an invalid `Module`. 656 657The linker function roughly corresponds to the implementation-defined 658[HostResolveImportedModule][] abstract operation in the ECMAScript 659specification, with a few key differences: 660 661* The linker function is allowed to be asynchronous while 662 [HostResolveImportedModule][] is synchronous. 663 664The actual [HostResolveImportedModule][] implementation used during module 665linking is one that returns the modules linked during linking. Since at 666that point all modules would have been fully linked already, the 667[HostResolveImportedModule][] implementation is fully synchronous per 668specification. 669 670Corresponds to the [Link() concrete method][] field of [Cyclic Module 671Record][]s in the ECMAScript specification. 672 673### `module.namespace` 674 675* {Object} 676 677The namespace object of the module. This is only available after linking 678(`module.link()`) has completed. 679 680Corresponds to the [GetModuleNamespace][] abstract operation in the ECMAScript 681specification. 682 683### `module.status` 684 685* {string} 686 687The current status of the module. Will be one of: 688 689* `'unlinked'`: `module.link()` has not yet been called. 690 691* `'linking'`: `module.link()` has been called, but not all Promises returned 692 by the linker function have been resolved yet. 693 694* `'linked'`: The module has been linked successfully, and all of its 695 dependencies are linked, but `module.evaluate()` has not yet been called. 696 697* `'evaluating'`: The module is being evaluated through a `module.evaluate()` on 698 itself or a parent module. 699 700* `'evaluated'`: The module has been successfully evaluated. 701 702* `'errored'`: The module has been evaluated, but an exception was thrown. 703 704Other than `'errored'`, this status string corresponds to the specification's 705[Cyclic Module Record][]'s `[[Status]]` field. `'errored'` corresponds to 706`'evaluated'` in the specification, but with `[[EvaluationError]]` set to a 707value that is not `undefined`. 708 709## Class: `vm.SourceTextModule` 710 711<!-- YAML 712added: v9.6.0 713--> 714 715> Stability: 1 - Experimental 716 717This feature is only available with the `--experimental-vm-modules` command 718flag enabled. 719 720* Extends: {vm.Module} 721 722The `vm.SourceTextModule` class provides the [Source Text Module Record][] as 723defined in the ECMAScript specification. 724 725### `new vm.SourceTextModule(code[, options])` 726 727<!-- YAML 728changes: 729 - version: 730 - v17.0.0 731 - v16.12.0 732 pr-url: https://github.com/nodejs/node/pull/40249 733 description: Added support for import assertions to the 734 `importModuleDynamically` parameter. 735--> 736 737* `code` {string} JavaScript Module code to parse 738* `options` 739 * `identifier` {string} String used in stack traces. 740 **Default:** `'vm:module(i)'` where `i` is a context-specific ascending 741 index. 742 * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or 743 `TypedArray`, or `DataView` with V8's code cache data for the supplied 744 source. The `code` must be the same as the module from which this 745 `cachedData` was created. 746 * `context` {Object} The [contextified][] object as returned by the 747 `vm.createContext()` method, to compile and evaluate this `Module` in. 748 If no context is specified, the module is evaluated in the current 749 execution context. 750 * `lineOffset` {integer} Specifies the line number offset that is displayed 751 in stack traces produced by this `Module`. **Default:** `0`. 752 * `columnOffset` {integer} Specifies the first-line column number offset that 753 is displayed in stack traces produced by this `Module`. **Default:** `0`. 754 * `initializeImportMeta` {Function} Called during evaluation of this `Module` 755 to initialize the `import.meta`. 756 * `meta` {import.meta} 757 * `module` {vm.SourceTextModule} 758 * `importModuleDynamically` {Function} Called during evaluation of this module 759 when `import()` is called. If this option is not specified, calls to 760 `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. 761 * `specifier` {string} specifier passed to `import()` 762 * `module` {vm.Module} 763 * `importAssertions` {Object} The `"assert"` value passed to the 764 [`optionsExpression`][] optional parameter, or an empty object if no value 765 was provided. 766 * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is 767 recommended in order to take advantage of error tracking, and to avoid 768 issues with namespaces that contain `then` function exports. 769 770Creates a new `SourceTextModule` instance. 771 772Properties assigned to the `import.meta` object that are objects may 773allow the module to access information outside the specified `context`. Use 774`vm.runInContext()` to create objects in a specific context. 775 776```mjs 777import vm from 'node:vm'; 778 779const contextifiedObject = vm.createContext({ secret: 42 }); 780 781const module = new vm.SourceTextModule( 782 'Object.getPrototypeOf(import.meta.prop).secret = secret;', 783 { 784 initializeImportMeta(meta) { 785 // Note: this object is created in the top context. As such, 786 // Object.getPrototypeOf(import.meta.prop) points to the 787 // Object.prototype in the top context rather than that in 788 // the contextified object. 789 meta.prop = {}; 790 }, 791 }); 792// Since module has no dependencies, the linker function will never be called. 793await module.link(() => {}); 794await module.evaluate(); 795 796// Now, Object.prototype.secret will be equal to 42. 797// 798// To fix this problem, replace 799// meta.prop = {}; 800// above with 801// meta.prop = vm.runInContext('{}', contextifiedObject); 802``` 803 804```cjs 805const vm = require('node:vm'); 806const contextifiedObject = vm.createContext({ secret: 42 }); 807(async () => { 808 const module = new vm.SourceTextModule( 809 'Object.getPrototypeOf(import.meta.prop).secret = secret;', 810 { 811 initializeImportMeta(meta) { 812 // Note: this object is created in the top context. As such, 813 // Object.getPrototypeOf(import.meta.prop) points to the 814 // Object.prototype in the top context rather than that in 815 // the contextified object. 816 meta.prop = {}; 817 }, 818 }); 819 // Since module has no dependencies, the linker function will never be called. 820 await module.link(() => {}); 821 await module.evaluate(); 822 // Now, Object.prototype.secret will be equal to 42. 823 // 824 // To fix this problem, replace 825 // meta.prop = {}; 826 // above with 827 // meta.prop = vm.runInContext('{}', contextifiedObject); 828})(); 829``` 830 831### `sourceTextModule.createCachedData()` 832 833<!-- YAML 834added: 835 - v13.7.0 836 - v12.17.0 837--> 838 839* Returns: {Buffer} 840 841Creates a code cache that can be used with the `SourceTextModule` constructor's 842`cachedData` option. Returns a `Buffer`. This method may be called any number 843of times before the module has been evaluated. 844 845The code cache of the `SourceTextModule` doesn't contain any JavaScript 846observable states. The code cache is safe to be saved along side the script 847source and used to construct new `SourceTextModule` instances multiple times. 848 849Functions in the `SourceTextModule` source can be marked as lazily compiled 850and they are not compiled at construction of the `SourceTextModule`. These 851functions are going to be compiled when they are invoked the first time. The 852code cache serializes the metadata that V8 currently knows about the 853`SourceTextModule` that it can use to speed up future compilations. 854 855```js 856// Create an initial module 857const module = new vm.SourceTextModule('const a = 1;'); 858 859// Create cached data from this module 860const cachedData = module.createCachedData(); 861 862// Create a new module using the cached data. The code must be the same. 863const module2 = new vm.SourceTextModule('const a = 1;', { cachedData }); 864``` 865 866## Class: `vm.SyntheticModule` 867 868<!-- YAML 869added: 870 - v13.0.0 871 - v12.16.0 872--> 873 874> Stability: 1 - Experimental 875 876This feature is only available with the `--experimental-vm-modules` command 877flag enabled. 878 879* Extends: {vm.Module} 880 881The `vm.SyntheticModule` class provides the [Synthetic Module Record][] as 882defined in the WebIDL specification. The purpose of synthetic modules is to 883provide a generic interface for exposing non-JavaScript sources to ECMAScript 884module graphs. 885 886```js 887const vm = require('node:vm'); 888 889const source = '{ "a": 1 }'; 890const module = new vm.SyntheticModule(['default'], function() { 891 const obj = JSON.parse(source); 892 this.setExport('default', obj); 893}); 894 895// Use `module` in linking... 896``` 897 898### `new vm.SyntheticModule(exportNames, evaluateCallback[, options])` 899 900<!-- YAML 901added: 902 - v13.0.0 903 - v12.16.0 904--> 905 906* `exportNames` {string\[]} Array of names that will be exported from the 907 module. 908* `evaluateCallback` {Function} Called when the module is evaluated. 909* `options` 910 * `identifier` {string} String used in stack traces. 911 **Default:** `'vm:module(i)'` where `i` is a context-specific ascending 912 index. 913 * `context` {Object} The [contextified][] object as returned by the 914 `vm.createContext()` method, to compile and evaluate this `Module` in. 915 916Creates a new `SyntheticModule` instance. 917 918Objects assigned to the exports of this instance may allow importers of 919the module to access information outside the specified `context`. Use 920`vm.runInContext()` to create objects in a specific context. 921 922### `syntheticModule.setExport(name, value)` 923 924<!-- YAML 925added: 926 - v13.0.0 927 - v12.16.0 928--> 929 930* `name` {string} Name of the export to set. 931* `value` {any} The value to set the export to. 932 933This method is used after the module is linked to set the values of exports. If 934it is called before the module is linked, an [`ERR_VM_MODULE_STATUS`][] error 935will be thrown. 936 937```mjs 938import vm from 'node:vm'; 939 940const m = new vm.SyntheticModule(['x'], () => { 941 m.setExport('x', 1); 942}); 943 944await m.link(() => {}); 945await m.evaluate(); 946 947assert.strictEqual(m.namespace.x, 1); 948``` 949 950```cjs 951const vm = require('node:vm'); 952(async () => { 953 const m = new vm.SyntheticModule(['x'], () => { 954 m.setExport('x', 1); 955 }); 956 await m.link(() => {}); 957 await m.evaluate(); 958 assert.strictEqual(m.namespace.x, 1); 959})(); 960``` 961 962## `vm.compileFunction(code[, params[, options]])` 963 964<!-- YAML 965added: v10.10.0 966changes: 967 - version: 968 - v18.15.0 969 pr-url: https://github.com/nodejs/node/pull/46320 970 description: The return value now includes `cachedDataRejected` 971 with the same semantics as the `vm.Script` version 972 if the `cachedData` option was passed. 973 - version: 974 - v17.0.0 975 - v16.12.0 976 pr-url: https://github.com/nodejs/node/pull/40249 977 description: Added support for import assertions to the 978 `importModuleDynamically` parameter. 979 - version: v15.9.0 980 pr-url: https://github.com/nodejs/node/pull/35431 981 description: Added `importModuleDynamically` option again. 982 - version: v14.3.0 983 pr-url: https://github.com/nodejs/node/pull/33364 984 description: Removal of `importModuleDynamically` due to compatibility 985 issues. 986 - version: 987 - v14.1.0 988 - v13.14.0 989 pr-url: https://github.com/nodejs/node/pull/32985 990 description: The `importModuleDynamically` option is now supported. 991--> 992 993* `code` {string} The body of the function to compile. 994* `params` {string\[]} An array of strings containing all parameters for the 995 function. 996* `options` {Object} 997 * `filename` {string} Specifies the filename used in stack traces produced 998 by this script. **Default:** `''`. 999 * `lineOffset` {number} Specifies the line number offset that is displayed 1000 in stack traces produced by this script. **Default:** `0`. 1001 * `columnOffset` {number} Specifies the first-line column number offset that 1002 is displayed in stack traces produced by this script. **Default:** `0`. 1003 * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or 1004 `TypedArray`, or `DataView` with V8's code cache data for the supplied 1005 source. This must be produced by a prior call to [`vm.compileFunction()`][] 1006 with the same `code` and `params`. 1007 * `produceCachedData` {boolean} Specifies whether to produce new cache data. 1008 **Default:** `false`. 1009 * `parsingContext` {Object} The [contextified][] object in which the said 1010 function should be compiled in. 1011 * `contextExtensions` {Object\[]} An array containing a collection of context 1012 extensions (objects wrapping the current scope) to be applied while 1013 compiling. **Default:** `[]`. 1014 * `importModuleDynamically` {Function} Called during evaluation of this module 1015 when `import()` is called. If this option is not specified, calls to 1016 `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. 1017 This option is part of the experimental modules API, and should not be 1018 considered stable. 1019 * `specifier` {string} specifier passed to `import()` 1020 * `function` {Function} 1021 * `importAssertions` {Object} The `"assert"` value passed to the 1022 [`optionsExpression`][] optional parameter, or an empty object if no value 1023 was provided. 1024 * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is 1025 recommended in order to take advantage of error tracking, and to avoid 1026 issues with namespaces that contain `then` function exports. 1027* Returns: {Function} 1028 1029Compiles the given code into the provided context (if no context is 1030supplied, the current context is used), and returns it wrapped inside a 1031function with the given `params`. 1032 1033## `vm.createContext([contextObject[, options]])` 1034 1035<!-- YAML 1036added: v0.3.1 1037changes: 1038 - version: v14.6.0 1039 pr-url: https://github.com/nodejs/node/pull/34023 1040 description: The `microtaskMode` option is supported now. 1041 - version: v10.0.0 1042 pr-url: https://github.com/nodejs/node/pull/19398 1043 description: The first argument can no longer be a function. 1044 - version: v10.0.0 1045 pr-url: https://github.com/nodejs/node/pull/19016 1046 description: The `codeGeneration` option is supported now. 1047--> 1048 1049* `contextObject` {Object} 1050* `options` {Object} 1051 * `name` {string} Human-readable name of the newly created context. 1052 **Default:** `'VM Context i'`, where `i` is an ascending numerical index of 1053 the created context. 1054 * `origin` {string} [Origin][origin] corresponding to the newly created 1055 context for display purposes. The origin should be formatted like a URL, 1056 but with only the scheme, host, and port (if necessary), like the value of 1057 the [`url.origin`][] property of a [`URL`][] object. Most notably, this 1058 string should omit the trailing slash, as that denotes a path. 1059 **Default:** `''`. 1060 * `codeGeneration` {Object} 1061 * `strings` {boolean} If set to false any calls to `eval` or function 1062 constructors (`Function`, `GeneratorFunction`, etc) will throw an 1063 `EvalError`. **Default:** `true`. 1064 * `wasm` {boolean} If set to false any attempt to compile a WebAssembly 1065 module will throw a `WebAssembly.CompileError`. **Default:** `true`. 1066 * `microtaskMode` {string} If set to `afterEvaluate`, microtasks (tasks 1067 scheduled through `Promise`s and `async function`s) will be run immediately 1068 after a script has run through [`script.runInContext()`][]. 1069 They are included in the `timeout` and `breakOnSigint` scopes in that case. 1070* Returns: {Object} contextified object. 1071 1072If given a `contextObject`, the `vm.createContext()` method will [prepare 1073that object][contextified] so that it can be used in calls to 1074[`vm.runInContext()`][] or [`script.runInContext()`][]. Inside such scripts, 1075the `contextObject` will be the global object, retaining all of its existing 1076properties but also having the built-in objects and functions any standard 1077[global object][] has. Outside of scripts run by the vm module, global variables 1078will remain unchanged. 1079 1080```js 1081const vm = require('node:vm'); 1082 1083global.globalVar = 3; 1084 1085const context = { globalVar: 1 }; 1086vm.createContext(context); 1087 1088vm.runInContext('globalVar *= 2;', context); 1089 1090console.log(context); 1091// Prints: { globalVar: 2 } 1092 1093console.log(global.globalVar); 1094// Prints: 3 1095``` 1096 1097If `contextObject` is omitted (or passed explicitly as `undefined`), a new, 1098empty [contextified][] object will be returned. 1099 1100The `vm.createContext()` method is primarily useful for creating a single 1101context that can be used to run multiple scripts. For instance, if emulating a 1102web browser, the method can be used to create a single context representing a 1103window's global object, then run all `<script>` tags together within that 1104context. 1105 1106The provided `name` and `origin` of the context are made visible through the 1107Inspector API. 1108 1109## `vm.isContext(object)` 1110 1111<!-- YAML 1112added: v0.11.7 1113--> 1114 1115* `object` {Object} 1116* Returns: {boolean} 1117 1118Returns `true` if the given `object` object has been [contextified][] using 1119[`vm.createContext()`][]. 1120 1121## `vm.measureMemory([options])` 1122 1123<!-- YAML 1124added: v13.10.0 1125--> 1126 1127> Stability: 1 - Experimental 1128 1129Measure the memory known to V8 and used by all contexts known to the 1130current V8 isolate, or the main context. 1131 1132* `options` {Object} Optional. 1133 * `mode` {string} Either `'summary'` or `'detailed'`. In summary mode, 1134 only the memory measured for the main context will be returned. In 1135 detailed mode, the memory measured for all contexts known to the 1136 current V8 isolate will be returned. 1137 **Default:** `'summary'` 1138 * `execution` {string} Either `'default'` or `'eager'`. With default 1139 execution, the promise will not resolve until after the next scheduled 1140 garbage collection starts, which may take a while (or never if the program 1141 exits before the next GC). With eager execution, the GC will be started 1142 right away to measure the memory. 1143 **Default:** `'default'` 1144* Returns: {Promise} If the memory is successfully measured, the promise will 1145 resolve with an object containing information about the memory usage. 1146 Otherwise it will be rejected with an `ERR_CONTEXT_NOT_INITIALIZED` error. 1147 1148The format of the object that the returned Promise may resolve with is 1149specific to the V8 engine and may change from one version of V8 to the next. 1150 1151The returned result is different from the statistics returned by 1152`v8.getHeapSpaceStatistics()` in that `vm.measureMemory()` measure the 1153memory reachable by each V8 specific contexts in the current instance of 1154the V8 engine, while the result of `v8.getHeapSpaceStatistics()` measure 1155the memory occupied by each heap space in the current V8 instance. 1156 1157```js 1158const vm = require('node:vm'); 1159// Measure the memory used by the main context. 1160vm.measureMemory({ mode: 'summary' }) 1161 // This is the same as vm.measureMemory() 1162 .then((result) => { 1163 // The current format is: 1164 // { 1165 // total: { 1166 // jsMemoryEstimate: 2418479, jsMemoryRange: [ 2418479, 2745799 ] 1167 // } 1168 // } 1169 console.log(result); 1170 }); 1171 1172const context = vm.createContext({ a: 1 }); 1173vm.measureMemory({ mode: 'detailed', execution: 'eager' }) 1174 .then((result) => { 1175 // Reference the context here so that it won't be GC'ed 1176 // until the measurement is complete. 1177 console.log(context.a); 1178 // { 1179 // total: { 1180 // jsMemoryEstimate: 2574732, 1181 // jsMemoryRange: [ 2574732, 2904372 ] 1182 // }, 1183 // current: { 1184 // jsMemoryEstimate: 2438996, 1185 // jsMemoryRange: [ 2438996, 2768636 ] 1186 // }, 1187 // other: [ 1188 // { 1189 // jsMemoryEstimate: 135736, 1190 // jsMemoryRange: [ 135736, 465376 ] 1191 // } 1192 // ] 1193 // } 1194 console.log(result); 1195 }); 1196``` 1197 1198## `vm.runInContext(code, contextifiedObject[, options])` 1199 1200<!-- YAML 1201added: v0.3.1 1202changes: 1203 - version: 1204 - v17.0.0 1205 - v16.12.0 1206 pr-url: https://github.com/nodejs/node/pull/40249 1207 description: Added support for import assertions to the 1208 `importModuleDynamically` parameter. 1209 - version: v6.3.0 1210 pr-url: https://github.com/nodejs/node/pull/6635 1211 description: The `breakOnSigint` option is supported now. 1212--> 1213 1214* `code` {string} The JavaScript code to compile and run. 1215* `contextifiedObject` {Object} The [contextified][] object that will be used 1216 as the `global` when the `code` is compiled and run. 1217* `options` {Object|string} 1218 * `filename` {string} Specifies the filename used in stack traces produced 1219 by this script. **Default:** `'evalmachine.<anonymous>'`. 1220 * `lineOffset` {number} Specifies the line number offset that is displayed 1221 in stack traces produced by this script. **Default:** `0`. 1222 * `columnOffset` {number} Specifies the first-line column number offset that 1223 is displayed in stack traces produced by this script. **Default:** `0`. 1224 * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs 1225 while compiling the `code`, the line of code causing the error is attached 1226 to the stack trace. **Default:** `true`. 1227 * `timeout` {integer} Specifies the number of milliseconds to execute `code` 1228 before terminating execution. If execution is terminated, an [`Error`][] 1229 will be thrown. This value must be a strictly positive integer. 1230 * `breakOnSigint` {boolean} If `true`, receiving `SIGINT` 1231 (<kbd>Ctrl</kbd>+<kbd>C</kbd>) will terminate execution and throw an 1232 [`Error`][]. Existing handlers for the event that have been attached via 1233 `process.on('SIGINT')` are disabled during script execution, but continue to 1234 work after that. **Default:** `false`. 1235 * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or 1236 `TypedArray`, or `DataView` with V8's code cache data for the supplied 1237 source. 1238 * `importModuleDynamically` {Function} Called during evaluation of this module 1239 when `import()` is called. If this option is not specified, calls to 1240 `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. 1241 This option is part of the experimental modules API. We do not recommend 1242 using it in a production environment. 1243 * `specifier` {string} specifier passed to `import()` 1244 * `script` {vm.Script} 1245 * `importAssertions` {Object} The `"assert"` value passed to the 1246 [`optionsExpression`][] optional parameter, or an empty object if no value 1247 was provided. 1248 * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is 1249 recommended in order to take advantage of error tracking, and to avoid 1250 issues with namespaces that contain `then` function exports. 1251* Returns: {any} the result of the very last statement executed in the script. 1252 1253The `vm.runInContext()` method compiles `code`, runs it within the context of 1254the `contextifiedObject`, then returns the result. Running code does not have 1255access to the local scope. The `contextifiedObject` object _must_ have been 1256previously [contextified][] using the [`vm.createContext()`][] method. 1257 1258If `options` is a string, then it specifies the filename. 1259 1260The following example compiles and executes different scripts using a single 1261[contextified][] object: 1262 1263```js 1264const vm = require('node:vm'); 1265 1266const contextObject = { globalVar: 1 }; 1267vm.createContext(contextObject); 1268 1269for (let i = 0; i < 10; ++i) { 1270 vm.runInContext('globalVar *= 2;', contextObject); 1271} 1272console.log(contextObject); 1273// Prints: { globalVar: 1024 } 1274``` 1275 1276## `vm.runInNewContext(code[, contextObject[, options]])` 1277 1278<!-- YAML 1279added: v0.3.1 1280changes: 1281 - version: 1282 - v17.0.0 1283 - v16.12.0 1284 pr-url: https://github.com/nodejs/node/pull/40249 1285 description: Added support for import assertions to the 1286 `importModuleDynamically` parameter. 1287 - version: v14.6.0 1288 pr-url: https://github.com/nodejs/node/pull/34023 1289 description: The `microtaskMode` option is supported now. 1290 - version: v10.0.0 1291 pr-url: https://github.com/nodejs/node/pull/19016 1292 description: The `contextCodeGeneration` option is supported now. 1293 - version: v6.3.0 1294 pr-url: https://github.com/nodejs/node/pull/6635 1295 description: The `breakOnSigint` option is supported now. 1296--> 1297 1298* `code` {string} The JavaScript code to compile and run. 1299* `contextObject` {Object} An object that will be [contextified][]. If 1300 `undefined`, a new object will be created. 1301* `options` {Object|string} 1302 * `filename` {string} Specifies the filename used in stack traces produced 1303 by this script. **Default:** `'evalmachine.<anonymous>'`. 1304 * `lineOffset` {number} Specifies the line number offset that is displayed 1305 in stack traces produced by this script. **Default:** `0`. 1306 * `columnOffset` {number} Specifies the first-line column number offset that 1307 is displayed in stack traces produced by this script. **Default:** `0`. 1308 * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs 1309 while compiling the `code`, the line of code causing the error is attached 1310 to the stack trace. **Default:** `true`. 1311 * `timeout` {integer} Specifies the number of milliseconds to execute `code` 1312 before terminating execution. If execution is terminated, an [`Error`][] 1313 will be thrown. This value must be a strictly positive integer. 1314 * `breakOnSigint` {boolean} If `true`, receiving `SIGINT` 1315 (<kbd>Ctrl</kbd>+<kbd>C</kbd>) will terminate execution and throw an 1316 [`Error`][]. Existing handlers for the event that have been attached via 1317 `process.on('SIGINT')` are disabled during script execution, but continue to 1318 work after that. **Default:** `false`. 1319 * `contextName` {string} Human-readable name of the newly created context. 1320 **Default:** `'VM Context i'`, where `i` is an ascending numerical index of 1321 the created context. 1322 * `contextOrigin` {string} [Origin][origin] corresponding to the newly 1323 created context for display purposes. The origin should be formatted like a 1324 URL, but with only the scheme, host, and port (if necessary), like the 1325 value of the [`url.origin`][] property of a [`URL`][] object. Most notably, 1326 this string should omit the trailing slash, as that denotes a path. 1327 **Default:** `''`. 1328 * `contextCodeGeneration` {Object} 1329 * `strings` {boolean} If set to false any calls to `eval` or function 1330 constructors (`Function`, `GeneratorFunction`, etc) will throw an 1331 `EvalError`. **Default:** `true`. 1332 * `wasm` {boolean} If set to false any attempt to compile a WebAssembly 1333 module will throw a `WebAssembly.CompileError`. **Default:** `true`. 1334 * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or 1335 `TypedArray`, or `DataView` with V8's code cache data for the supplied 1336 source. 1337 * `importModuleDynamically` {Function} Called during evaluation of this module 1338 when `import()` is called. If this option is not specified, calls to 1339 `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. 1340 This option is part of the experimental modules API. We do not recommend 1341 using it in a production environment. 1342 * `specifier` {string} specifier passed to `import()` 1343 * `script` {vm.Script} 1344 * `importAssertions` {Object} The `"assert"` value passed to the 1345 [`optionsExpression`][] optional parameter, or an empty object if no value 1346 was provided. 1347 * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is 1348 recommended in order to take advantage of error tracking, and to avoid 1349 issues with namespaces that contain `then` function exports. 1350 * `microtaskMode` {string} If set to `afterEvaluate`, microtasks (tasks 1351 scheduled through `Promise`s and `async function`s) will be run immediately 1352 after the script has run. They are included in the `timeout` and 1353 `breakOnSigint` scopes in that case. 1354* Returns: {any} the result of the very last statement executed in the script. 1355 1356The `vm.runInNewContext()` first contextifies the given `contextObject` (or 1357creates a new `contextObject` if passed as `undefined`), compiles the `code`, 1358runs it within the created context, then returns the result. Running code 1359does not have access to the local scope. 1360 1361If `options` is a string, then it specifies the filename. 1362 1363The following example compiles and executes code that increments a global 1364variable and sets a new one. These globals are contained in the `contextObject`. 1365 1366```js 1367const vm = require('node:vm'); 1368 1369const contextObject = { 1370 animal: 'cat', 1371 count: 2, 1372}; 1373 1374vm.runInNewContext('count += 1; name = "kitty"', contextObject); 1375console.log(contextObject); 1376// Prints: { animal: 'cat', count: 3, name: 'kitty' } 1377``` 1378 1379## `vm.runInThisContext(code[, options])` 1380 1381<!-- YAML 1382added: v0.3.1 1383changes: 1384 - version: 1385 - v17.0.0 1386 - v16.12.0 1387 pr-url: https://github.com/nodejs/node/pull/40249 1388 description: Added support for import assertions to the 1389 `importModuleDynamically` parameter. 1390 - version: v6.3.0 1391 pr-url: https://github.com/nodejs/node/pull/6635 1392 description: The `breakOnSigint` option is supported now. 1393--> 1394 1395* `code` {string} The JavaScript code to compile and run. 1396* `options` {Object|string} 1397 * `filename` {string} Specifies the filename used in stack traces produced 1398 by this script. **Default:** `'evalmachine.<anonymous>'`. 1399 * `lineOffset` {number} Specifies the line number offset that is displayed 1400 in stack traces produced by this script. **Default:** `0`. 1401 * `columnOffset` {number} Specifies the first-line column number offset that 1402 is displayed in stack traces produced by this script. **Default:** `0`. 1403 * `displayErrors` {boolean} When `true`, if an [`Error`][] occurs 1404 while compiling the `code`, the line of code causing the error is attached 1405 to the stack trace. **Default:** `true`. 1406 * `timeout` {integer} Specifies the number of milliseconds to execute `code` 1407 before terminating execution. If execution is terminated, an [`Error`][] 1408 will be thrown. This value must be a strictly positive integer. 1409 * `breakOnSigint` {boolean} If `true`, receiving `SIGINT` 1410 (<kbd>Ctrl</kbd>+<kbd>C</kbd>) will terminate execution and throw an 1411 [`Error`][]. Existing handlers for the event that have been attached via 1412 `process.on('SIGINT')` are disabled during script execution, but continue to 1413 work after that. **Default:** `false`. 1414 * `cachedData` {Buffer|TypedArray|DataView} Provides an optional `Buffer` or 1415 `TypedArray`, or `DataView` with V8's code cache data for the supplied 1416 source. 1417 * `importModuleDynamically` {Function} Called during evaluation of this module 1418 when `import()` is called. If this option is not specified, calls to 1419 `import()` will reject with [`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`][]. 1420 This option is part of the experimental modules API. We do not recommend 1421 using it in a production environment. 1422 * `specifier` {string} specifier passed to `import()` 1423 * `script` {vm.Script} 1424 * `importAssertions` {Object} The `"assert"` value passed to the 1425 [`optionsExpression`][] optional parameter, or an empty object if no value 1426 was provided. 1427 * Returns: {Module Namespace Object|vm.Module} Returning a `vm.Module` is 1428 recommended in order to take advantage of error tracking, and to avoid 1429 issues with namespaces that contain `then` function exports. 1430* Returns: {any} the result of the very last statement executed in the script. 1431 1432`vm.runInThisContext()` compiles `code`, runs it within the context of the 1433current `global` and returns the result. Running code does not have access to 1434local scope, but does have access to the current `global` object. 1435 1436If `options` is a string, then it specifies the filename. 1437 1438The following example illustrates using both `vm.runInThisContext()` and 1439the JavaScript [`eval()`][] function to run the same code: 1440 1441<!-- eslint-disable prefer-const --> 1442 1443```js 1444const vm = require('node:vm'); 1445let localVar = 'initial value'; 1446 1447const vmResult = vm.runInThisContext('localVar = "vm";'); 1448console.log(`vmResult: '${vmResult}', localVar: '${localVar}'`); 1449// Prints: vmResult: 'vm', localVar: 'initial value' 1450 1451const evalResult = eval('localVar = "eval";'); 1452console.log(`evalResult: '${evalResult}', localVar: '${localVar}'`); 1453// Prints: evalResult: 'eval', localVar: 'eval' 1454``` 1455 1456Because `vm.runInThisContext()` does not have access to the local scope, 1457`localVar` is unchanged. In contrast, [`eval()`][] _does_ have access to the 1458local scope, so the value `localVar` is changed. In this way 1459`vm.runInThisContext()` is much like an [indirect `eval()` call][], e.g. 1460`(0,eval)('code')`. 1461 1462## Example: Running an HTTP server within a VM 1463 1464When using either [`script.runInThisContext()`][] or 1465[`vm.runInThisContext()`][], the code is executed within the current V8 global 1466context. The code passed to this VM context will have its own isolated scope. 1467 1468In order to run a simple web server using the `node:http` module the code passed 1469to the context must either call `require('node:http')` on its own, or have a 1470reference to the `node:http` module passed to it. For instance: 1471 1472```js 1473'use strict'; 1474const vm = require('node:vm'); 1475 1476const code = ` 1477((require) => { 1478 const http = require('node:http'); 1479 1480 http.createServer((request, response) => { 1481 response.writeHead(200, { 'Content-Type': 'text/plain' }); 1482 response.end('Hello World\\n'); 1483 }).listen(8124); 1484 1485 console.log('Server running at http://127.0.0.1:8124/'); 1486})`; 1487 1488vm.runInThisContext(code)(require); 1489``` 1490 1491The `require()` in the above case shares the state with the context it is 1492passed from. This may introduce risks when untrusted code is executed, e.g. 1493altering objects in the context in unwanted ways. 1494 1495## What does it mean to "contextify" an object? 1496 1497All JavaScript executed within Node.js runs within the scope of a "context". 1498According to the [V8 Embedder's Guide][]: 1499 1500> In V8, a context is an execution environment that allows separate, unrelated, 1501> JavaScript applications to run in a single instance of V8. You must explicitly 1502> specify the context in which you want any JavaScript code to be run. 1503 1504When the method `vm.createContext()` is called, the `contextObject` argument 1505(or a newly-created object if `contextObject` is `undefined`) is associated 1506internally with a new instance of a V8 Context. This V8 Context provides the 1507`code` run using the `node:vm` module's methods with an isolated global 1508environment within which it can operate. The process of creating the V8 Context 1509and associating it with the `contextObject` is what this document refers to as 1510"contextifying" the object. 1511 1512## Timeout interactions with asynchronous tasks and Promises 1513 1514`Promise`s and `async function`s can schedule tasks run by the JavaScript 1515engine asynchronously. By default, these tasks are run after all JavaScript 1516functions on the current stack are done executing. 1517This allows escaping the functionality of the `timeout` and 1518`breakOnSigint` options. 1519 1520For example, the following code executed by `vm.runInNewContext()` with a 1521timeout of 5 milliseconds schedules an infinite loop to run after a promise 1522resolves. The scheduled loop is never interrupted by the timeout: 1523 1524```js 1525const vm = require('node:vm'); 1526 1527function loop() { 1528 console.log('entering loop'); 1529 while (1) console.log(Date.now()); 1530} 1531 1532vm.runInNewContext( 1533 'Promise.resolve().then(() => loop());', 1534 { loop, console }, 1535 { timeout: 5 }, 1536); 1537// This is printed *before* 'entering loop' (!) 1538console.log('done executing'); 1539``` 1540 1541This can be addressed by passing `microtaskMode: 'afterEvaluate'` to the code 1542that creates the `Context`: 1543 1544```js 1545const vm = require('node:vm'); 1546 1547function loop() { 1548 while (1) console.log(Date.now()); 1549} 1550 1551vm.runInNewContext( 1552 'Promise.resolve().then(() => loop());', 1553 { loop, console }, 1554 { timeout: 5, microtaskMode: 'afterEvaluate' }, 1555); 1556``` 1557 1558In this case, the microtask scheduled through `promise.then()` will be run 1559before returning from `vm.runInNewContext()`, and will be interrupted 1560by the `timeout` functionality. This applies only to code running in a 1561`vm.Context`, so e.g. [`vm.runInThisContext()`][] does not take this option. 1562 1563Promise callbacks are entered into the microtask queue of the context in which 1564they were created. For example, if `() => loop()` is replaced with just `loop` 1565in the above example, then `loop` will be pushed into the global microtask 1566queue, because it is a function from the outer (main) context, and thus will 1567also be able to escape the timeout. 1568 1569If asynchronous scheduling functions such as `process.nextTick()`, 1570`queueMicrotask()`, `setTimeout()`, `setImmediate()`, etc. are made available 1571inside a `vm.Context`, functions passed to them will be added to global queues, 1572which are shared by all contexts. Therefore, callbacks passed to those functions 1573are not controllable through the timeout either. 1574 1575[Cyclic Module Record]: https://tc39.es/ecma262/#sec-cyclic-module-records 1576[ECMAScript Module Loader]: esm.md#modules-ecmascript-modules 1577[Evaluate() concrete method]: https://tc39.es/ecma262/#sec-moduleevaluation 1578[GetModuleNamespace]: https://tc39.es/ecma262/#sec-getmodulenamespace 1579[HostResolveImportedModule]: https://tc39.es/ecma262/#sec-hostresolveimportedmodule 1580[Link() concrete method]: https://tc39.es/ecma262/#sec-moduledeclarationlinking 1581[Module Record]: https://www.ecma-international.org/ecma-262/#sec-abstract-module-records 1582[Source Text Module Record]: https://tc39.es/ecma262/#sec-source-text-module-records 1583[Synthetic Module Record]: https://heycam.github.io/webidl/#synthetic-module-records 1584[V8 Embedder's Guide]: https://v8.dev/docs/embed#contexts 1585[`ERR_VM_DYNAMIC_IMPORT_CALLBACK_MISSING`]: errors.md#err_vm_dynamic_import_callback_missing 1586[`ERR_VM_MODULE_STATUS`]: errors.md#err_vm_module_status 1587[`Error`]: errors.md#class-error 1588[`URL`]: url.md#class-url 1589[`eval()`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval 1590[`optionsExpression`]: https://tc39.es/proposal-import-attributes/#sec-evaluate-import-call 1591[`script.runInContext()`]: #scriptrunincontextcontextifiedobject-options 1592[`script.runInThisContext()`]: #scriptruninthiscontextoptions 1593[`url.origin`]: url.md#urlorigin 1594[`vm.compileFunction()`]: #vmcompilefunctioncode-params-options 1595[`vm.createContext()`]: #vmcreatecontextcontextobject-options 1596[`vm.runInContext()`]: #vmrunincontextcode-contextifiedobject-options 1597[`vm.runInThisContext()`]: #vmruninthiscontextcode-options 1598[contextified]: #what-does-it-mean-to-contextify-an-object 1599[global object]: https://es5.github.io/#x15.1 1600[indirect `eval()` call]: https://es5.github.io/#x10.4.2 1601[origin]: https://developer.mozilla.org/en-US/docs/Glossary/Origin 1602