Repository: nodejs/node
Pull request: doc: add esm and cjs examples to `node:vm`

This PR adds the missing `ESM` and `CJS` examples to their respective counterparts for the [VM documentation](https://nodejs.org/api/vm.html).

For the [`SyntheticModule`](https://nodejs.org/api/vm.html#class-vmsyntheticmodule) example I added the linking part just to showcase the new default.

For the [`vm.measureMemory([options])` ](https://nodejs.org/api/vm.html#vmmeasurememoryoptions)example I updated the format being shown, it used to be:
```js
{
  total: {
    jsMemoryEstimate: 2418479,
    jsMemoryRange: [2418479, 2745799],
  },
}
```

And now it's:
```js
{
  total: { jsMemoryEstimate: 1601828, jsMemoryRange: [1601828, 5275288] },
  WebAssembly: { code: 0, metadata: 33962 },
}
```

For the example in [`What does it mean to "contextify" an object?`](https://nodejs.org/api/vm.html#what-does-it-mean-to-contextify-an-object) I changed the error printing so we only show the expected `TypeError: Cannot freeze` instead of the whole error stack so now instead of seeing this:
```bash
evalmachine.<anonymous>:1
Object.freeze(globalThis);
       ^

TypeError: Cannot freeze
    at Object.freeze (<anonymous>)
    at evalmachine.<anonymous>:1:8
    at Script.runInContext (node:vm:149:12)
    at runInContext (node:vm:301:6)
    at Object.<anonymous> (/home/alpi/Documents/prjct/node/esm-vm/12globalContextify.js:8:3)
    at Module._compile (node:internal/modules/cjs/loader:1760:14)
    at Object..js (node:internal/modules/cjs/loader:1892:10)
    at Module.load (node:internal/modules/cjs/loader:1480:32)
    at Module._load (node:internal/modules/cjs/loader:1299:12)
    at TracingChannel.traceSync (node:diagnostics_channel:328:14)
```

We see this:
```bash
TypeError: Cannot freeze
```

I did the same for the [`vm.constants.DONT_CONTEXTIFY`](https://nodejs.org/api/vm.html#vmconstantsdont_contextify) examples.

Also, I believe there was a typo in the code snippet for the [`When microtaskMode is 'afterEvaluate', beware sharing Promises between Contexts`](https://nodejs.org/api/vm.html#when-microtaskmode-is-afterevaluate-beware-sharing-promises-between-contexts), we where using `context` when in reality it should've been `inner_context`, I have fixed that. For that one I'm adding it's `CJS` counterpart.

I've tested all examples included in this PR and they all work/behave as expected now.

Thanks again for everything!

Changed files:
filename: doc/api/vm.md
patch: @@ -25,23 +25,42 @@ object. The invoked code treats any property in the context like a
 global variable. Any changes to global variables caused by the invoked
 code are reflected in the context object.
 
-```js
-const vm = require('node:vm');
+```mjs
+import { createContext, runInContext } from 'node:vm';
+
+const x = 1;
+
+const context = { x: 2 };
+createContext(context); // Contextify the object.
+
+const code = 'x += 40; var y = 17;';
+// `x` and `y` are global variables in the context.
+// Initially, x has the value 2 because that is the value of context.x.
+runInContext(code, context);
+
+console.log(context.x); // 42
+console.log(context.y); // 17
+
+console.log(x); // 1; y is not defined
+```
+
+```cjs
+const { createContext, runInContext } = require('node:vm');
 
 const x = 1;
 
 const context = { x: 2 };
-vm.createContext(context); // Contextify the object.
+createContext(context); // Contextify the object.
 
 const code = 'x += 40; var y = 17;';
 // `x` and `y` are global variables in the context.
 // Initially, x has the value 2 because that is the value of context.x.
-vm.runInContext(code, context);
+runInContext(code, context);
 
 console.log(context.x); // 42
 console.log(context.y); // 17
 
-console.log(x); // 1; y is not defined.
+console.log(x); // 1; y is not defined
 ```
 
 ## Class: `vm.Script`
@@ -201,17 +220,36 @@ The following example compiles code that increments a global variable, sets
 the value of another global variable, then execute the code multiple times.
 The globals are contained in the `context` object.
 
-```js
-const vm = require('node:vm');
+```mjs
+import { createContext, Script } from 'node:vm';
 
 const context = {
   animal: 'cat',
   count: 2,
 };
 
-const script = new vm.Script('count += 1; name = "kitty";');
+const script = new Script('count += 1; name = "kitty";');
 
-vm.createContext(context);
+createContext(context);
+for (let i = 0; i < 10; ++i) {
+  script.runInContext(context);
+}
+
+console.log(context);
+// Prints: { animal: 'cat', count: 12, name: 'kitty' }
+```
+
+```cjs
+const { createContext, Script } = require('node:vm');
+
+const context = {
+  animal: 'cat',
+  count: 2,
+};
+
+const script = new Script('count += 1; name = "kitty";');
+
+createContext(context);
 for (let i = 0; i < 10; ++i) {
   script.runInContext(context);
 }
@@ -296,10 +334,30 @@ The following example compiles code that sets a global variable, then executes
 the code multiple times in different contexts. The globals are set on and
 contained within each individual `context`.
 
-```js
-const vm = require('node:vm');
+```mjs
+import { constants, Script } from 'node:vm';
+
+const script = new Script('globalVar = "set"');
+
+const contexts = [{}, {}, {}];
+contexts.forEach((context) => {
+  script.runInNewContext(context);
+});
+
+console.log(contexts);
+// Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]
+
+// This would throw if the context is created from a contextified object.
+// constants.DONT_CONTEXTIFY allows creating contexts with ordinary
+// global objects that can be frozen.
+const freezeScript = new Script('Object.freeze(globalThis); globalThis;');
+const frozenContext = freezeScript.runInNewContext(constants.DONT_CONTEXTIFY);
+```
+
+```cjs
+const { constants, Script } = require('node:vm');
 
-const script = new vm.Script('globalVar = "set"');
+const script = new Script('globalVar = "set"');
 
 const contexts = [{}, {}, {}];
 contexts.forEach((context) => {
@@ -310,10 +368,10 @@ console.log(contexts);
 // Prints: [{ globalVar: 'set' }, { globalVar: 'set' }, { globalVar: 'set' }]
 
 // This would throw if the context is created from a contextified object.
-// vm.constants.DONT_CONTEXTIFY allows creating contexts with ordinary
+// constants.DONT_CONTEXTIFY allows creating contexts with ordinary
 // global objects that can be frozen.
-const freezeScript = new vm.Script('Object.freeze(globalThis); globalThis;');
-const frozenContext = freezeScript.runInNewContext(vm.constants.DONT_CONTEXTIFY);
+const freezeScript = new Script('Object.freeze(globalThis); globalThis;');
+const frozenContext = freezeScript.runInNewContext(constants.DONT_CONTEXTIFY);
 ```
 
 ### `script.runInThisContext([options])`
@@ -347,12 +405,28 @@ _does_ have access to the current `global` object.
 The following example compiles code that increments a `global` variable then
 executes that code multiple times:
 
-```js
-const vm = require('node:vm');
+```mjs
+import { Script } from 'node:vm';
 
 global.globalVar = 0;
 
-const script = new vm.Script('globalVar += 1', { filename: 'myfile.vm' });
+const script = new Script('globalVar += 1', { filename: 'myfile.vm' });
+
+for (let i = 0; i < 1000; ++i) {
+  script.runInThisContext();
+}
+
+console.log(globalVar);
+
+// 1000
+```
+
+```cjs
+const { Script } = require('node:vm');
+
+global.globalVar = 0;
+
+const script = new Script('globalVar += 1', { filename: 'myfile.vm' });
 
 for (let i = 0; i < 1000; ++i) {
   script.runInThisContext();
@@ -1126,16 +1200,40 @@ defined in the WebIDL specification. The purpose of synthetic modules is to
 provide a generic interface for exposing non-JavaScript sources to ECMAScript
 module graphs.
 
-```js
-const vm = require('node:vm');
+```mjs
+import { SyntheticModule } from 'node:vm';
+
+const source = '{ "a": 1 }';
+const syntheticModule = new SyntheticModule(['default'], function() {
+  const obj = JSON.parse(source);
+  this.setExport('default', obj);
+});
+
+// Use `syntheticModule` in linking
+(async () => {
+  await syntheticModule.link(() => {});
+  await syntheticModule.evaluate();
+
+  console.log('Default export:', syntheticModule.namespace.default);
+})();
+```
+
+```cjs
+const { SyntheticModule } = require('node:vm');
 
 const source = '{ "a": 1 }';
-const module = new vm.SyntheticModule(['default'], function() {
+const syntheticModule = new SyntheticModule(['default'], function() {
   const obj = JSON.parse(source);
   this.setExport('default', obj);
 });
 
-// Use `module` in linking...
+// Use `syntheticModule` in linking
+(async () => {
+  await syntheticModule.link(() => {});
+  await syntheticModule.evaluate();
+
+  console.log('Default export:', syntheticModule.namespace.default);
+})();
 ```
 
 ### `new vm.SyntheticModule(exportNames, evaluateCallback[, options])`
@@ -1395,15 +1493,32 @@ existing properties but also having the built-in objects and functions any
 standard [global object][] has. Outside of scripts run by the vm module, global
 variables will remain unchanged.
 
-```js
-const vm = require('node:vm');
+```mjs
+import { createContext, runInContext } from 'node:vm';
+
+global.globalVar = 3;
+
+const context = { globalVar: 1 };
+createContext(context);
+
+runInContext('globalVar *= 2;', context);
+
+console.log(context);
+// Prints: { globalVar: 2 }
+
+console.log(global.globalVar);
+// Prints: 3
+```
+
+```cjs
+const { createContext, runInContext } = require('node:vm');
 
 global.globalVar = 3;
 
 const context = { globalVar: 1 };
-vm.createContext(context);
+createContext(context);
 
-vm.runInContext('globalVar *= 2;', context);
+runInContext('globalVar *= 2;', context);
 
 console.log(context);
 // Prints: { globalVar: 2 }
@@ -1478,45 +1593,62 @@ memory reachable by each V8 specific contexts in the current instance of
 the V8 engine, while the result of `v8.getHeapSpaceStatistics()` measure
 the memory occupied by each heap space in the current V8 instance.
 
-```js
-const vm = require('node:vm');
+```mjs
+import { createContext, measureMemory } from 'node:vm';
 // Measure the memory used by the main context.
-vm.measureMemory({ mode: 'summary' })
+measureMemory({ mode: 'summary' })
   // This is the same as vm.measureMemory()
   .then((result) => {
     // The current format is:
     // {
-    //   total: {
-    //      jsMemoryEstimate: 2418479, jsMemoryRange: [ 2418479, 2745799 ]
-    //    }
+    //   total: { jsMemoryEstimate: 1601828, jsMemoryRange: [1601828, 5275288] },
+    //   WebAssembly: { code: 0, metadata: 33962 },
     // }
     console.log(result);
   });
 
-const context = vm.createContext({ a: 1 });
-vm.measureMemory({ mode: 'detailed', execution: 'eager' })
+const context = createContext({ a: 1 });
+measureMemory({ mode: 'detailed', execution: 'eager' }).then((result) => {
+  // Reference the context here so that it won't be GC'ed
+  // until the measurement is complete.
+  console.log('Context:', context.a);
+  // {
+  //   total: { jsMemoryEstimate: 1767100, jsMemoryRange: [1767100, 5440560] },
+  //   WebAssembly: { code: 0, metadata: 33962 },
+  //   current: { jsMemoryEstimate: 1601828, jsMemoryRange: [1601828, 5275288] },
+  //   other: [{ jsMemoryEstimate: 165272, jsMemoryRange: [Array] }],
+  // }
+  console.log(result);
+});
+```
+
+```cjs
+const { createContext, measureMemory } = require('node:vm');
+// Measure the memory used by the main context.
+measureMemory({ mode: 'summary' })
+  // This is the same as vm.measureMemory()
   .then((result) => {
-    // Reference the context here so that it won't be GC'ed
-    // until the measurement is complete.
-    console.log(context.a);
+    // The current format is:
     // {
-    //   total: {
-    //     jsMemoryEstimate: 2574732,
-    //     jsMemoryRange: [ 2574732, 2904372 ]
-    //   },
-    //   current: {
-    //     jsMemoryEstimate: 2438996,
-    //     jsMemoryRange: [ 2438996, 2768636 ]
-    //   },
-    //   other: [
-    //     {
-    //       jsMemoryEstimate: 135736,
-    //       jsMemoryRange: [ 135736, 465376 ]
-    //     }
-    //   ]
+    //   total: { jsMemoryEstimate: 1601828, jsMemoryRange: [1601828, 5275288] },
+    //   WebAssembly: { code: 0, metadata: 33962 },
     // }
     console.log(result);
   });
+
+const context = createContext({ a: 1 });
+measureMemory({ mode: 'detailed', execution: 'eager' }).then((result) => {
+  // Reference the context here so that it won't be GC'ed
+  // until the measurement is complete.
+  console.log('Context:', context.a);
+  // {
+  //   total: { jsMemoryEstimate: 1767100, jsMemoryRange: [1767100, 5440560] },
+  //   WebAssembly: { code: 0, metadata: 33962 },
+  //   current: { jsMemoryEstimate: 1601828, jsMemoryRange: [1601828, 5275288] },
+  //   other: [{ jsMemoryEstimate: 165272, jsMemoryRange: [Array] }],
+  // }
+  console.log(result);
+});
 ```
 
 ## `vm.runInContext(code, contextifiedObject[, options])`
@@ -1583,14 +1715,27 @@ If `options` is a string, then it specifies the filename.
 The following example compiles and executes different scripts using a single
 [contextified][] object:
 
-```js
-const vm = require('node:vm');
+```mjs
+import { createContext, runInContext } from 'node:vm';
 
 const contextObject = { globalVar: 1 };
-vm.createContext(contextObject);
+createContext(contextObject);
 
 for (let i = 0; i < 10; ++i) {
-  vm.runInContext('globalVar *= 2;', contextObject);
+  runInContext('globalVar *= 2;', contextObject);
+}
+console.log(contextObject);
+// Prints: { globalVar: 1024 }
+```
+
+```cjs
+const { createContext, runInContext } = require('node:vm');
+
+const contextObject = { globalVar: 1 };
+createContext(contextObject);
+
+for (let i = 0; i < 10; ++i) {
+  runInContext('globalVar *= 2;', contextObject);
 }
 console.log(contextObject);
 // Prints: { globalVar: 1024 }
@@ -1700,22 +1845,46 @@ It does several things at once:
 The following example compiles and executes code that increments a global
 variable and sets a new one. These globals are contained in the `contextObject`.
 
-```js
-const vm = require('node:vm');
+```mjs
+import { runInNewContext, constants } from 'node:vm';
 
 const contextObject = {
   animal: 'cat',
   count: 2,
 };
 
-vm.runInNewContext('count += 1; name = "kitty"', contextObject);
+runInNewContext('count += 1; name = "kitty"', contextObject);
 console.log(contextObject);
 // Prints: { animal: 'cat', count: 3, name: 'kitty' }
 
 // This would throw if the context is created from a contextified object.
 // vm.constants.DONT_CONTEXTIFY allows creating contexts with ordinary global objects that
 // can be frozen.
-const frozenContext = vm.runInNewContext('Object.freeze(globalThis); globalThis;', vm.constants.DONT_CONTEXTIFY);
+const frozenContext = runInNewContext(
+  'Object.freeze(globalThis); globalThis;',
+  constants.DONT_CONTEXTIFY,
+);
+```
+
+```cjs
+const { runInNewContext, constants } = require('node:vm');
+
+const contextObject = {
+  animal: 'cat',
+  count: 2,
+};
+
+runInNewContext('count += 1; name = "kitty"', contextObject);
+console.log(contextObject);
+// Prints: { animal: 'cat', count: 3, name: 'kitty' }
+
+// This would throw if the context is created from a contextified object.
+// vm.constants.DONT_CONTEXTIFY allows creating contexts with ordinary global objects that
+// can be frozen.
+const frozenContext = runInNewContext(
+  'Object.freeze(globalThis); globalThis;',
+  constants.DONT_CONTEXTIFY,
+);
 ```
 
 ## `vm.runInThisContext(code[, options])`
@@ -1782,11 +1951,26 @@ the JavaScript [`eval()`][] function to run the same code:
 
 <!-- eslint-disable prefer-const -->
 
-```js
-const vm = require('node:vm');
+```mjs
+import { runInThisContext } from 'node:vm';
 let localVar = 'initial value';
 
-const vmResult = vm.runInThisContext('localVar = "vm";');
+const vmResult = runInThisContext('localVar = "vm";');
+console.log(`vmResult: '${vmResult}', localVar: '${localVar}'`);
+// Prints: vmResult: 'vm', localVar: 'initial value'
+
+const evalResult = eval('localVar = "eval";');
+console.log(`evalResult: '${evalResult}', localVar: '${localVar}'`);
+// Prints: evalResult: 'eval', localVar: 'eval'
+```
+
+<!-- eslint-disable prefer-const -->
+
+```cjs
+const { runInThisContext } = require('node:vm');
+let localVar = 'initial value';
+
+const vmResult = runInThisContext('localVar = "vm";');
 console.log(`vmResult: '${vmResult}', localVar: '${localVar}'`);
 // Prints: vmResult: 'vm', localVar: 'initial value'
 
@@ -1811,23 +1995,43 @@ In order to run a simple web server using the `node:http` module the code passed
 to the context must either call `require('node:http')` on its own, or have a
 reference to the `node:http` module passed to it. For instance:
 
-```js
-'use strict';
-const vm = require('node:vm');
+```mjs
+import { runInThisContext } from 'node:vm';
+import { createRequire } from 'node:module';
+
+const require = createRequire(import.meta.url);
 
 const code = `
 ((require) => {
-  const http = require('node:http');
+  const { createServer } = require('node:http');
 
-  http.createServer((request, response) => {
+  createServer((request, response) => {
     response.writeHead(200, { 'Content-Type': 'text/plain' });
     response.end('Hello World\\n');
   }).listen(8124);
 
   console.log('Server running at http://127.0.0.1:8124/');
 })`;
 
-vm.runInThisContext(code)(require);
+runInThisContext(code)(require);
+```
+
+```cjs
+const { runInThisContext } = require('node:vm');
+
+const code = `
+((require) => {
+  const { createServer } = require('node:http');
+
+  createServer((request, response) => {
+    response.writeHead(200, { 'Content-Type': 'text/plain' });
+    response.end('Hello World\\n');
+  }).listen(8124);
+
+  console.log('Server running at http://127.0.0.1:8124/');
+})`;
+
+runInThisContext(code)(require);
 ```
 
 The `require()` in the above case shares the state with the context it is
@@ -1855,19 +2059,34 @@ The contextifying would introduce some quirks to the `globalThis` value in the c
 For example, it cannot be frozen, and it is not reference equal to the `contextObject`
 in the outer context.
 
-```js
-const vm = require('node:vm');
+```mjs
+import { createContext, runInContext } from 'node:vm';
 
 // An undefined `contextObject` option makes the global object contextified.
-const context = vm.createContext();
-console.log(vm.runInContext('globalThis', context) === context);  // false
+const context = createContext();
+console.log(runInContext('globalThis', context) === context);  // false
 // A contextified global object cannot be frozen.
 try {
-  vm.runInContext('Object.freeze(globalThis);', context);
+  runInContext('Object.freeze(globalThis);', context);
 } catch (e) {
-  console.log(e); // TypeError: Cannot freeze
+  console.log(`${e.constructor.name}: ${e.message}`); // TypeError: Cannot freeze
 }
-console.log(vm.runInContext('globalThis.foo = 1; foo;', context));  // 1
+console.log(runInContext('globalThis.foo = 1; foo;', context));  // 1
+```
+
+```cjs
+const { createContext, runInContext } = require('node:vm');
+
+// An undefined `contextObject` option makes the global object contextified.
+const context = createContext();
+console.log(runInContext('globalThis', context) === context);  // false
+// A contextified global object cannot be frozen.
+try {
+  runInContext('Object.freeze(globalThis);', context);
+} catch (e) {
+  console.log(`${e.constructor.name}: ${e.message}`); // TypeError: Cannot freeze
+}
+console.log(runInContext('globalThis.foo = 1; foo;', context));  // 1
 ```
 
 To create a context with an ordinary global object and get access to a global proxy in
@@ -1881,16 +2100,29 @@ a context without wrapping its global object with another object in a Node.js-sp
 As a result, the `globalThis` value inside the new context would behave more closely to an ordinary
 one.
 
-```js
-const vm = require('node:vm');
+```mjs
+import { createContext, runInContext, constants } from 'node:vm';
+
+// Use vm.constants.DONT_CONTEXTIFY to freeze the global object.
+const context = createContext(constants.DONT_CONTEXTIFY);
+runInContext('Object.freeze(globalThis);', context);
+try {
+  runInContext('bar = 1; bar;', context);
+} catch (e) {
+  console.log(`${e.constructor.name}: ${e.message}`); // ReferenceError: bar is not defined
+}
+```
+
+```cjs
+const { createContext, runInContext, constants } = require('node:vm');
 
 // Use vm.constants.DONT_CONTEXTIFY to freeze the global object.
-const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);
-vm.runInContext('Object.freeze(globalThis);', context);
+const context = createContext(constants.DONT_CONTEXTIFY);
+runInContext('Object.freeze(globalThis);', context);
 try {
-  vm.runInContext('bar = 1; bar;', context);
+  runInContext('bar = 1; bar;', context);
 } catch (e) {
-  console.log(e); // Uncaught ReferenceError: bar is not defined
+  console.log(`${e.constructor.name}: ${e.message}`); // ReferenceError: bar is not defined
 }
 ```
 
@@ -1899,27 +2131,51 @@ the returned object is a proxy-like object to the global object in the newly cre
 fewer Node.js-specific quirks. It is reference equal to the `globalThis` value in the new context,
 can be modified from outside the context, and can be used to access built-ins in the new context directly.
 
-```js
-const vm = require('node:vm');
+```mjs
+import { createContext, runInContext, constants } from 'node:vm';
+
+const context = createContext(constants.DONT_CONTEXTIFY);
+
+// Returned object is reference equal to globalThis in the new context.
+console.log(runInContext('globalThis', context) === context);  // true
+
+// Can be used to access globals in the new context directly.
+console.log(context.Array);  // [Function: Array]
+runInContext('foo = 1;', context);
+console.log(context.foo);  // 1
+context.bar = 1;
+console.log(runInContext('bar;', context));  // 1
+
+// Can be frozen and it affects the inner context.
+Object.freeze(context);
+try {
+  runInContext('baz = 1; baz;', context);
+} catch (e) {
+  console.log(`${e.constructor.name}: ${e.message}`); // ReferenceError: baz is not defined
+}
+```
 
-const context = vm.createContext(vm.constants.DONT_CONTEXTIFY);
+```cjs
+const { createContext, runInContext, constants } = require('node:vm');
+
+const context = createContext(constants.DONT_CONTEXTIFY);
 
 // Returned object is reference equal to globalThis in the new context.
-console.log(vm.runInContext('globalThis', context) === context);  // true
+console.log(runInContext('globalThis', context) === context);  // true
 
 // Can be used to access globals in the new context directly.
 console.log(context.Array);  // [Function: Array]
-vm.runInContext('foo = 1;', context);
+runInContext('foo = 1;', context);
 console.log(context.foo);  // 1
 context.bar = 1;
-console.log(vm.runInContext('bar;', context));  // 1
+console.log(runInContext('bar;', context));  // 1
 
 // Can be frozen and it affects the inner context.
 Object.freeze(context);
 try {
-  vm.runInContext('baz = 1; baz;', context);
+  runInContext('baz = 1; baz;', context);
 } catch (e) {
-  console.log(e); // Uncaught ReferenceError: baz is not defined
+  console.log(`${e.constructor.name}: ${e.message}`); // ReferenceError: baz is not defined
 }
 ```
 
@@ -1935,34 +2191,65 @@ For example, the following code executed by `vm.runInNewContext()` with a
 timeout of 5 milliseconds schedules an infinite loop to run after a promise
 resolves. The scheduled loop is never interrupted by the timeout:
 
-```js
-const vm = require('node:vm');
+```mjs
+import { runInNewContext } from 'node:vm';
+
+function loop() {
+  console.log('entering loop');
+  while (1) console.log(Date.now());
+}
+
+runInNewContext(
+  'Promise.resolve().then(() => loop());',
+  { loop, console },
+  { timeout: 5 },
+);
+// This is printed *before* 'entering infinite loop' (!)
+console.log('done executing');
+```
+
+```cjs
+const { runInNewContext } = require('node:vm');
 
 function loop() {
   console.log('entering loop');
   while (1) console.log(Date.now());
 }
 
-vm.runInNewContext(
+runInNewContext(
   'Promise.resolve().then(() => loop());',
   { loop, console },
   { timeout: 5 },
 );
-// This is printed *before* 'entering loop' (!)
+// This is printed *before* 'entering infinite loop' (!)
 console.log('done executing');
 ```
 
 This can be addressed by passing `microtaskMode: 'afterEvaluate'` to the code
 that creates the `Context`:
 
-```js
-const vm = require('node:vm');
+```mjs
+import { runInNewContext } from 'node:vm';
+
+function loop() {
+  while (1) console.log(Date.now());
+}
+
+runInNewContext(
+  'Promise.resolve().then(() => loop());',
+  { loop, console },
+  { timeout: 5, microtaskMode: 'afterEvaluate' },
+);
+```
+
+```cjs
+const { runInNewContext } = require('node:vm');
 
 function loop() {
   while (1) console.log(Date.now());
 }
 
-vm.runInNewContext(
+runInNewContext(
   'Promise.resolve().then(() => loop());',
   { loop, console },
   { timeout: 5, microtaskMode: 'afterEvaluate' },
@@ -1999,15 +2286,12 @@ flow of the outer context is disrupted in a surprising way: the log statement
 is never executed.
 
 ```mjs
-import * as vm from 'node:vm';
+import { createContext, runInContext } from 'node:vm';
 
-const inner_context = vm.createContext({}, { microtaskMode: 'afterEvaluate' });
+const inner_context = createContext({}, { microtaskMode: 'afterEvaluate' });
 
 // runInContext() returns a Promise created in the inner context.
-const inner_promise = vm.runInContext(
-  'Promise.resolve()',
-  context,
-);
+const inner_promise = runInContext('Promise.resolve()', inner_context);
 
 // As part of performing `await`, the JavaScript runtime must enqueue a task
 // on the microtask queue of the context where `inner_promise` was created.
@@ -2021,6 +2305,28 @@ await inner_promise;
 console.log('this will NOT be printed');
 ```
 
+```cjs
+const { createContext, runInContext } = require('node:vm');
+
+// runInContext() returns a Promise created in the inner context.
+const inner_context = createContext({}, { microtaskMode: 'afterEvaluate' });
+
+(async () => {
+  const inner_promise = runInContext('Promise.resolve()', inner_context);
+
+  // As part of performing `await`, the JavaScript runtime must enqueue a task
+  // on the microtask queue of the context where `inner_promise` was created.
+  // A task is added on the inner microtask queue, but **it will not be run
+  // automatically**: this task will remain pending indefinitely.
+  //
+  // Since the outer microtask queue is empty, execution in the outer module
+  // falls through, and the log statement below is never executed.
+  await inner_promise;
+
+  console.log('this will NOT be printed');
+})();
+```
+
 To successfully share promises between contexts with different microtask queues,
 it is necessary to ensure that tasks on the inner microtask queue will be run
 **whenever** the outer context enqueues a task on the inner microtask queue.