-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
vm: adds runInModuleContext() #4955
vm: adds runInModuleContext() #4955
Conversation
var script = new Script(require('module').wrap(code), options); | ||
return script.runInThisContext(options)(exports, require, module, | ||
__filename, | ||
__dirname); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's not 'run in global context', that's 'run in the context of the vm module'.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't that be the only possibility to have a similar experience like in global context? What would you suggest?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe runInModuleContext
? Although it's not clear what the name "module" refers to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried just not wrapping it, but this but again throw ReferenceError: require is not defined
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the vm module's module
object (as is exports
). This function is essentially vm.runInVmContext()
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renaming would be fine for me. I am just looking for ways to have similar require
behaviour...while not having the signature as in the description of course. Anyhow it would just be sugar.(good -> less doc explanation sugar)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I meant it's not clear to end users what "module" in the name would refer to. But yea, just passing vm's values through isn't great.
Sorry, but this implementation is incorrect |
You might want to take a look at the real module system ( |
The purpose would be to pass everything from the global scope into the scope of the vm. Implementation-wise I am happy for input. Apart from that, can you advise on any other way to be able to |
Reference would be this comment |
I don't think it's possible |
None of those variables come from the global scope. Each one has its own unique value in every module. If you want to have access to their values in the current file, you would have to pass them in as arguments. |
@vkurchatkin I don't necessarily want global scope, but basically just use require-module-system. The use case would be to send a |
it would be confusing. |
@eljefedelrodeodeljefe I put together |
Okay. Edited this especially the name const vmResult = vm.runInThisContext(require('module').wrap(`
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/');
`))(exports, require, module) 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/');
`) |
@eljefedelrodeodeljefe When exactly would one use that? The module system used to have an undocumented switch to load each module in a separate vm context but, besides being badly broken for most of its existence, I don't think there really ever was a good use case for. I've never seen one, at least. (In case you're wondering why the switch existed in the first place: it was added very early on in node's life, for no real reason other than 'because we can'.) |
@bnoordhuis I am hacking on a |
So basically doing this meta programming would also be possible with the solution I am proposing right in |
This implementation is not really useful. Why would someone want |
Well |
sandboxing means to give explicit access to objects. That's exactly what you are trying to avoid.
Have what? Current implementation will only cause more confusion |
Sorry, but I find telling people to do this (below) or const vmResult = vm.runInThisContext(require('module').wrap(`
// code
`))(exports, require, module) And still I don't see much pointing against the implementation. Re: Sandboxing: I am not avoiding it. I just (and this my sole purpose) want to require modules like |
Your implementation is not equivalent to this code. It doesn't give access to current modules |
Yes and that's fine for me. I don't want to share anything, but run a server. Wherever the I also have no intimate knowledge of those modules, but this doesn't seem necessary in this context to me. If there is a non-eval way for running node.js code, please feel free to tell me. |
That's not a very good reason to include this in core.
So, |
Updated the branch. Apparently it's not necessary to pass the No, because Again. Having an API with function signatures like above and on open tickets in the archive repo, is worse then adding a couple of symbols to core, imo. If there is no consensus, I'll be fine. But this leaves me a little bit in disbelieve, tbh. |
Ok, I'm done arguing. Here are the problems with your code: Doesn't work: vm.runInModuleContext(`
var express = require('express');
`) Doesn't work: var a = 1;
vm.runInModuleContext(`
console.log(a);
`) Doesn't work: vm.runInModuleContext(`
exports.foo = 'bar';
`) Works, but it shouldn't vm.runInModuleContext(`
require('internal/module');
`) |
See, that is more productive. While case 2 and 3 are out my scope, 4 should not be possible and for, this should be made equivalent: (while the first works the second does not yet, but I put some work into it) vm.runInThisContext(require('module').wrap(`
var express = require('express');
var app = express();
app.get('/', function(req, res){
res.send('hello world');
});
app.listen(3000);
`))(exports, require)
vm.runInModuleContext(`
var express = require('express');
var app = express();
app.get('/', function(req, res){
res.send('hello world 2');
});
app.listen(3001);
`) |
@vkurchatkin worked on this. I think the update factors it all in. However one would need to pass it ass options, which might also be a good idea in the end. vm.runInThisContext(`
console.log(this);
`)
let options = {
passThrough: [ exports, require ]
}
var a = 1;
vm.runInModuleContext(`
var express = require('express');
var app = express();
app.get('/', function(req, res){
res.send('hello world 2');
});
app.listen(3001);
exports.foo = 'bar'; // -> works
// require('internal/module'); -> does not work, as expected
// console.log(a); -> does not work, but is okay
console.log(this); // should be same as in runInThisContext()
`, options) |
To be honest, I don't really see the value of this new method if you end up calling You mention you want to use it in a kind of in-memory |
Hm. Okay, so be it. No, the point would be to run it in another machine. However this was just the opportunity for me to find the This discussion was an attrition, shouldn't have started it. I'll just use the ugly code above. |
The intention behind is to present the user a way to execute code in a vm context. The current API doesn't allow this out-of-the-box, since it is neither passing a require function nor creating context with one. The missing docs for this behaviour have produced a number of Q&A items and have also been discussed in the node-archive repo. In both cases there was no real canonical answer. Refs: nodejs/node-v0.x-archive#9211, #4955 PR-URL: #5323 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: Myles Borins <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
The intention behind is to present the user a way to execute code in a vm context. The current API doesn't allow this out-of-the-box, since it is neither passing a require function nor creating context with one. The missing docs for this behaviour have produced a number of Q&A items and have also been discussed in the node-archive repo. In both cases there was no real canonical answer. Refs: nodejs/node-v0.x-archive#9211, nodejs#4955 PR-URL: nodejs#5323 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: Myles Borins <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
The intention behind is to present the user a way to execute code in a vm context. The current API doesn't allow this out-of-the-box, since it is neither passing a require function nor creating context with one. The missing docs for this behaviour have produced a number of Q&A items and have also been discussed in the node-archive repo. In both cases there was no real canonical answer. Refs: nodejs/node-v0.x-archive#9211, #4955 PR-URL: #5323 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: Myles Borins <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
The intention behind is to present the user a way to execute code in a vm context. The current API doesn't allow this out-of-the-box, since it is neither passing a require function nor creating context with one. The missing docs for this behaviour have produced a number of Q&A items and have also been discussed in the node-archive repo. In both cases there was no real canonical answer. Refs: nodejs/node-v0.x-archive#9211, #4955 PR-URL: #5323 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: Myles Borins <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
The intention behind is to present the user a way to execute code in a vm context. The current API doesn't allow this out-of-the-box, since it is neither passing a require function nor creating context with one. The missing docs for this behaviour have produced a number of Q&A items and have also been discussed in the node-archive repo. In both cases there was no real canonical answer. Refs: nodejs/node-v0.x-archive#9211, #4955 PR-URL: #5323 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: Myles Borins <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
The intention behind is to present the user a way to execute code in a vm context. The current API doesn't allow this out-of-the-box, since it is neither passing a require function nor creating context with one. The missing docs for this behaviour have produced a number of Q&A items and have also been discussed in the node-archive repo. In both cases there was no real canonical answer. Refs: nodejs/node-v0.x-archive#9211, #4955 PR-URL: #5323 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: Myles Borins <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
The intention behind is to present the user a way to execute code in a vm context. The current API doesn't allow this out-of-the-box, since it is neither passing a require function nor creating context with one. The missing docs for this behaviour have produced a number of Q&A items and have also been discussed in the node-archive repo. In both cases there was no real canonical answer. Refs: nodejs/node-v0.x-archive#9211, #4955 PR-URL: #5323 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: Myles Borins <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
The intention behind is to present the user a way to execute code in a vm context. The current API doesn't allow this out-of-the-box, since it is neither passing a require function nor creating context with one. The missing docs for this behaviour have produced a number of Q&A items and have also been discussed in the node-archive repo. In both cases there was no real canonical answer. Refs: nodejs/node-v0.x-archive#9211, #4955 PR-URL: #5323 Reviewed-By: James M Snell <[email protected]> Reviewed-By: Stephen Belanger <[email protected]> Reviewed-By: Myles Borins <[email protected]> Reviewed-By: Sakthipriyan Vairamani <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
With regards to nodejs/node-v0.x-archive#9211, this SO question and in order to prevent a signature like the below, I want to propose
vm.runInGlobalContext()
. This would make thevm
API more clear to users, who expect at least one methodvm
that behaves exactly like their global context.