Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion doc/api/vm.markdown
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ console.log('localVar: ', localVar);
// vmResult: 'vm', localVar: 'initial value'
// evalResult: 'eval', localVar: 'eval'
```

<a name="runInThisContext"></a>
`vm.runInThisContext` does not have access to the local scope, so `localVar` is
unchanged. `eval` does have access to the local scope, so `localVar` is changed.

Expand All @@ -297,6 +297,31 @@ e.g. `(0,eval)('code')`. However, it also has the following additional options:
- `timeout`: a number of milliseconds to execute `code` before terminating
execution. If execution is terminated, an [`Error`][] will be thrown.

## vm.runInModuleContext(code[, options])

`vm.runInModuleContext()` compiles `code`, runs it and returns the result. Running
code does not have access to local scope, but does have access to `module`,
`exports` and `require`. You can expect the script to behave similar to scripts
in the global context e.g. requiring global modules.

Example of using `vm.runInModuleContext` requiring `http` and a run a server:

```js
const vm = require('vm')

const vmResult = vm.runInModuleContext(`
const http = require('http');
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/');
`)
```

For options, see [`vm.runInThisContext()`](#runInThisContext)

[indirect `eval` call]: https://es5.github.io/#x10.4.2
[global object]: https://es5.github.io/#x15.1
[`Error`]: errors.html#errors_class_error
6 changes: 6 additions & 0 deletions lib/vm.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,4 +54,10 @@ exports.runInThisContext = function(code, options) {
return script.runInThisContext(options);
};

exports.runInModuleContext = function(code, options) {
var script = new Script(require('module').wrap(code), options);
let passThrough = options && options.passThrough ? options.passThrough : []
return script.runInThisContext(options).apply(null, passThrough);
};

exports.isContext = binding.isContext;
13 changes: 11 additions & 2 deletions test/parallel/test-vm-basic.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,25 @@ var result = vm.runInThisContext(
);
assert.strictEqual(global.vmResult, 'foo');
assert.strictEqual(result, '[object process]');

// Test 4: vm.runInGlobalContext
var result = vm.runInModuleContext(`
const path = require('path')
vmResult = path.dirname('/foo/bar/baz/asdf/quux');
Object.prototype.toString.call(process);`
);
assert.strictEqual(global.vmResult,
require('path').dirname('/foo/bar/baz/asdf/quux'));
delete global.vmResult;

// Test 4: vm.runInNewContext
// Test 5: vm.runInNewContext
var result = vm.runInNewContext(
'vmResult = "foo"; typeof process;'
);
assert.strictEqual(global.vmResult, undefined);
assert.strictEqual(result, 'undefined');

// Test 5: vm.createContext
// Test 6: vm.createContext
var sandbox3 = {};
var context2 = vm.createContext(sandbox3);
assert.strictEqual(sandbox3, context2);