Pass functions in a vm script context

时间:2016-07-11 21:59:42

标签: javascript node.js v8

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 个答案:

答案 0 :(得分:2)

实现此目的的一种方法是让您的lib模块成为一个接受上下文然后返回正确接口的函数。

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);