@@ -229,6 +229,9 @@ overhead.
229229<!-- YAML
230230added: v0.3.1
231231changes:
232+ - version: REPLACEME
233+ pr-url: https://github.com/nodejs/node/pull/54394
234+ description: The `contextObject` argument now accepts `vm.constants.DONT_CONTEXTIFY`.
232235 - version: v14.6.0
233236 pr-url: https://github.com/nodejs/node/pull/34023
234237 description: The `microtaskMode` option is supported now.
@@ -240,8 +243,9 @@ changes:
240243 description: The `breakOnSigint` option is supported now.
241244-->
242245
243- * ` contextObject ` {Object} An object that will be [ contextified] [ ] . If
244- ` undefined ` , a new object will be created.
246+ * ` contextObject ` {Object|vm.constants.DONT\_ CONTEXTIFY|undefined}
247+ Either [ ` vm.constants.DONT_CONTEXTIFY ` ] [ ] or an object that will be [ contextified] [ ] .
248+ If ` undefined ` , an empty contextified object will be created for backwards compatibility.
245249* ` options ` {Object}
246250 * ` displayErrors ` {boolean} When ` true ` , if an [ ` Error ` ] [ ] occurs
247251 while compiling the ` code ` , the line of code causing the error is attached
@@ -275,9 +279,16 @@ changes:
275279 ` breakOnSigint ` scopes in that case.
276280* Returns: {any} the result of the very last statement executed in the script.
277281
278- First contextifies the given ` contextObject ` , runs the compiled code contained
279- by the ` vm.Script ` object within the created context, and returns the result.
280- Running code does not have access to local scope.
282+ This method is a shortcut to ` script.runInContext(vm.createContext(options), options) ` .
283+ It does several things at once:
284+
285+ 1 . Creates a new context.
286+ 2 . If ` contextObject ` is an object, [ contextifies] [ contextified ] it with the new context.
287+ If ` contextObject ` is undefined, creates a new object and [ contextifies] [ contextified ] it.
288+ If ` contextObject ` is [ ` vm.constants.DONT_CONTEXTIFY ` ] [ ] , don't [ contextify] [ contextified ] anything.
289+ 3 . Runs the compiled code contained by the ` vm.Script ` object within the created context. The code
290+ does not have access to the scope in which this method is called.
291+ 4 . Returns the result.
281292
282293The following example compiles code that sets a global variable, then executes
283294the code multiple times in different contexts. The globals are set on and
@@ -295,6 +306,12 @@ contexts.forEach((context) => {
295306
296307console .log (contexts);
297308// Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]
309+
310+ // This would throw if the context is created from a contextified object.
311+ // vm.constants.DONT_CONTEXTIFY allows creating contexts with ordinary
312+ // global objects that can be frozen.
313+ const freezeScript = new vm.Script (' Object.freeze(globalThis); globalThis;' );
314+ const frozenContext = freezeScript .runInNewContext (vm .constants .DONT_CONTEXTIFY );
298315```
299316
300317### ` script.runInThisContext([options]) `
@@ -1072,6 +1089,10 @@ For detailed information, see
10721089<!-- YAML
10731090added: v0.3.1
10741091changes:
1092+ - version:
1093+ - REPLACEME
1094+ pr-url: https:// github.com/nodejs/node/pull/54394
1095+ description: The `contextObject` argument now accepts `vm.constants.DONT_CONTEXTIFY`.
10751096 - version:
10761097 - v21.7.0
10771098 - v20.12.0
@@ -1094,7 +1115,9 @@ changes:
10941115 description: The `codeGeneration` option is supported now.
10951116-->
10961117
1097- * `contextObject` {Object }
1118+ * `contextObject` {Object | vm .constants .DONT \_CONTEXTIFY | undefined }
1119+ Either [` vm.constants.DONT_CONTEXTIFY` ][] or an object that will be [contextified][].
1120+ If ` undefined` , an empty contextified object will be created for backwards compatibility.
10981121* ` options` {Object }
10991122 * ` name` {string} Human- readable name of the newly created context.
11001123 ** Default: ** ` 'VM Context i'` , where ` i` is an ascending numerical index of
@@ -1124,10 +1147,10 @@ changes:
11241147 [Support of dynamic ` import()` in compilation APIs][].
11251148* Returns: {Object } contextified object.
11261149
1127- If given a ` contextObject` , the ` vm.createContext()` method will [prepare that
1150+ If the given ` contextObject` is an object , the ` vm.createContext()` method will [prepare that
11281151object][contextified] and return a reference to it so that it can be used in
11291152calls to [` vm.runInContext()` ][] or [` script.runInContext()` ][]. Inside such
1130- scripts, the ` contextObject ` will be the global object , retaining all of its
1153+ scripts, the global object will be wrapped by the ` contextObject ` , retaining all of its
11311154existing properties but also having the built- in objects and functions any
11321155standard [global object][] has . Outside of scripts run by the vm module , global
11331156variables will remain unchanged.
@@ -1152,6 +1175,11 @@ console.log(global.globalVar);
11521175If ` contextObject` is omitted (or passed explicitly as ` undefined` ), a new ,
11531176empty [contextified][] object will be returned.
11541177
1178+ When the global object in the newly created context is [contextified][], it has some quirks
1179+ compared to ordinary global objects . For example, it cannot be frozen . To create a context
1180+ without the contextifying quirks, pass [` vm.constants.DONT_CONTEXTIFY` ][] as the ` contextObject`
1181+ argument . See the documentation of [` vm.constants.DONT_CONTEXTIFY` ][] for details.
1182+
11551183The ` vm.createContext()` method is primarily useful for creating a single
11561184context that can be used to run multiple scripts . For instance, if emulating a
11571185web browser, the method can be used to create a single context representing a
@@ -1171,7 +1199,8 @@ added: v0.11.7
11711199* Returns: {boolean}
11721200
11731201Returns `true` if the given `object` object has been [contextified][] using
1174- [`vm.createContext()`][].
1202+ [`vm.createContext()`][], or if it' s the global object of a context created
1203+ using [` vm.constants.DONT_CONTEXTIFY` ][].
11751204
11761205## ` vm.measureMemory([options])`
11771206
@@ -1332,6 +1361,10 @@ console.log(contextObject);
13321361<!-- YAML
13331362added: v0.3.1
13341363changes:
1364+ - version:
1365+ - REPLACEME
1366+ pr-url: https://github.com/nodejs/node/pull/54394
1367+ description: The `contextObject` argument now accepts `vm.constants.DONT_CONTEXTIFY`.
13351368 - version:
13361369 - v21.7.0
13371370 - v20.12.0
@@ -1356,8 +1389,9 @@ changes:
13561389-->
13571390
13581391* `code` {string} The JavaScript code to compile and run.
1359- * ` contextObject` {Object } An object that will be [contextified][]. If
1360- ` undefined` , a new object will be created.
1392+ * `contextObject` {Object|vm.constants.DONT\_ CONTEXTIFY|undefined}
1393+ Either [`vm.constants.DONT_CONTEXTIFY`][] or an object that will be [contextified][].
1394+ If `undefined`, an empty contextified object will be created for backwards compatibility.
13611395* `options` {Object|string}
13621396 * `filename` {string} Specifies the filename used in stack traces produced
13631397 by this script. **Default:** `' evalmachine.< anonymous> ' `.
@@ -1407,13 +1441,21 @@ changes:
14071441 ` breakOnSigint` scopes in that case.
14081442* Returns: {any} the result of the very last statement executed in the script.
14091443
1410- The `vm.runInNewContext()` first contextifies the given `contextObject` (or
1411- creates a new `contextObject` if passed as `undefined`), compiles the `code`,
1412- runs it within the created context, then returns the result. Running code
1413- does not have access to the local scope.
1414-
1444+ This method is a shortcut to
1445+ ` (new vm.Script(code, options)).runInContext(vm.createContext(options), options)` .
14151446If ` options` is a string, then it specifies the filename.
14161447
1448+ It does several things at once:
1449+
1450+ 1. Creates a new context.
1451+ 2. If ` contextObject` is an object, [contextifies][contextified] it with the new context.
1452+ If ` contextObject` is undefined , creates a new object and [contextifies][contextified] it.
1453+ If ` contextObject` is [` vm.constants.DONT_CONTEXTIFY` ][], don' t [contextify][contextified] anything.
1454+ 3. Compiles the code as a`vm.Script`
1455+ 4. Runs the compield code within the created context. The code does not have access to the scope in
1456+ which this method is called.
1457+ 5. Returns the result.
1458+
14171459The following example compiles and executes code that increments a global
14181460variable and sets a new one. These globals are contained in the `contextObject`.
14191461
@@ -1428,6 +1470,11 @@ const contextObject = {
14281470vm.runInNewContext(' count += 1 ; name = " kitty" ' , contextObject);
14291471console.log(contextObject);
14301472// Prints: { animal: ' cat' , count: 3, name: ' kitty' }
1473+
1474+ // This would throw if the context is created from a contextified object.
1475+ // vm.constants.DONT_CONTEXTIFY allows creating contexts with ordinary global objects that
1476+ // can be frozen.
1477+ const frozenContext = vm.runInNewContext(' Object .freeze (globalThis ); globalThis ;' , vm.constants.DONT_CONTEXTIFY);
14311478```
14321479
14331480## `vm.runInThisContext(code[, options])`
@@ -1555,13 +1602,85 @@ According to the [V8 Embedder's Guide][]:
15551602> JavaScript applications to run in a single instance of V8. You must explicitly
15561603> specify the context in which you want any JavaScript code to be run.
15571604
1558- When the method `vm.createContext()` is called, the `contextObject` argument
1559- (or a newly-created object if `contextObject` is `undefined`) is associated
1560- internally with a new instance of a V8 Context. This V8 Context provides the
1561- `code` run using the `node:vm` module' s methods with an isolated global
1562- environment within which it can operate . The process of creating the V8 Context
1563- and associating it with the ` contextObject` is what this document refers to as
1564- " contextifying" the object.
1605+ When the method `vm.createContext()` is called with an object, the `contextObject` argument
1606+ will be used to wrap the global object of a new instance of a V8 Context
1607+ (if `contextObject` is `undefined`, a new object will be created from the current context
1608+ before its contextified). This V8 Context provides the `code` run using the `node:vm`
1609+ module' s methods with an isolated global environment within which it can operate.
1610+ The process of creating the V8 Context and associating it with the ` contextObject`
1611+ in the outer context is what this document refers to as " contextifying" the object.
1612+
1613+ The contextifying would introduce some quirks to the ` globalThis` value in the context.
1614+ For example, it cannot be frozen, and it is not reference equal to the ` contextObject`
1615+ in the outer context.
1616+
1617+ ` ` ` js
1618+ const vm = require('node:vm');
1619+
1620+ // An undefined ` contextObject` option makes the global object contextified.
1621+ let context = vm.createContext();
1622+ console.log(vm.runInContext('globalThis', context) === context); // false
1623+ // A contextified global object cannot be frozen.
1624+ try {
1625+ vm.runInContext('Object.freeze(globalThis);', context);
1626+ } catch(e) {
1627+ console.log(e); // TypeError: Cannot freeze
1628+ }
1629+ console.log(vm.runInContext('globalThis.foo = 1; foo;', context)); // 1
1630+ ` ` `
1631+
1632+ To create a context with an ordinary global object and get access to a global proxy in
1633+ the outer context with fewer quirks, specify ` vm.constants.DONT_CONTEXTIFY` as the
1634+ ` contextObject` argument.
1635+
1636+ ### ` vm.constants.DONT_CONTEXTIFY`
1637+
1638+ This constant, when used as the ` contextObject` argument in vm APIs, instructs Node .js to create
1639+ a context without wrapping its global object with another object in a Node .js - specific manner.
1640+ As a result, the ` globalThis` value inside the new context would behave more closely to an ordinary
1641+ one.
1642+
1643+ ` ` ` js
1644+ const vm = require('node:vm');
1645+
1646+ // Use vm.constants.DONT_CONTEXTIFY to freeze the global object.
1647+ const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);
1648+ vm.runInContext('Object.freeze(globalThis);', context);
1649+ try {
1650+ vm.runInContext('bar = 1; bar;', context);
1651+ } catch(e) {
1652+ console.log(e); // Uncaught ReferenceError: bar is not defined
1653+ }
1654+ ` ` `
1655+
1656+ When ` vm.constants.DONT_CONTEXTIFY` is used as the ` contextObject` argument to [` vm.createContext()` ][],
1657+ the returned object is a proxy- like object to the global object in the newly created context with
1658+ fewer Node .js - specific quirks . It is reference equal to the ` globalThis` value in the new context ,
1659+ can be modified from outside the context, and can be used to access built- ins in the new context directly.
1660+
1661+ ` ` ` js
1662+ const vm = require('node:vm');
1663+
1664+ const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);
1665+
1666+ // Returned object is reference equal to globalThis in the new context.
1667+ console.log(vm.runInContext('globalThis', context) === context); // true
1668+
1669+ // Can be used to access globals in the new context directly.
1670+ console.log(context.Array); // [Function: Array]
1671+ vm.runInContext('foo = 1;', context);
1672+ console.log(context.foo); // 1
1673+ context.bar = 1;
1674+ console.log(vm.runInContext('bar;', context)); // 1
1675+
1676+ // Can be frozen and it affects the inner context.
1677+ Object.freeze(context);
1678+ try {
1679+ vm.runInContext('baz = 1; baz;', context);
1680+ } catch(e) {
1681+ console.log(e); // Uncaught ReferenceError: baz is not defined
1682+ }
1683+ ` ` `
15651684
15661685## Timeout interactions with asynchronous tasks and Promises
15671686
@@ -1851,6 +1970,7 @@ const { Script, SyntheticModule } = require('node:vm');
18511970[` script .runInThisContext ()` ]: #scriptruninthiscontextoptions
18521971[` url .origin ` ]: url.md#urlorigin
18531972[` vm .compileFunction ()` ]: #vmcompilefunctioncode-params-options
1973+ [` vm .constants .DONT_CONTEXTIFY ` ]: #vmconstantsdont_contextify
18541974[` vm .createContext ()` ]: #vmcreatecontextcontextobject-options
18551975[` vm .runInContext ()` ]: #vmrunincontextcode-contextifiedobject-options
18561976[` vm .runInThisContext ()` ]: #vmruninthiscontextcode-options
0 commit comments