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