问题
Let's say I have a library module that looks like this:
module.exports = {
increment: function() {
count++;
}
}
And I'd like to use it in a dynamically generated script that looks like this:
(function() { lib.increment(); })();
by passing it in a sandbox:
var sandbox = {
count: 1
lib: require('./lib')
}
var script = new vm.Script('(function() { lib.increment() })();');
script.runInNewContext(sandbox);
The obvious problem I run into is that I on the one hand can't require "lib" because "count" is not defined in lib.js ; on the other hand if I define var count
above the exports of the "lib.js" file, this new count
variable will be affected instead of the one in the sandbox.
Here are the constraints that I would like to respect:
- Use vm and not a eval() nor a require() on a generated file
- Have "lib" defined in a external file
- No modification of the automatically generated script, so no use of
lib.increment.apply(context)
or similar
The only solutions I've found so far is to prepend the lib
functions in the generated script as a string, or to define them directly on the sandbox
object, which I find to be a less desirable option.
There doesn't seem to be any way of passing a context of variables on the require
call.
回答1:
One way of accomplishing this is have your lib
module be a function that takes in a context then returns the correct interface.
lib.js
module.exports = function(context) {
var count = context.count;
return {
increment: function() {
count++;
}
};
};
main.js
var sandbox = {
count: 1
};
sandbox.lib = require('./lib')(sandbox);
var script = new vm.Script('(function() { lib.increment() })();');
script.runInNewContext(sandbox);
来源:https://stackoverflow.com/questions/38316876/pass-functions-in-a-vm-script-context