Pass functions in a vm script context

这一生的挚爱 提交于 2019-12-24 07:37:05

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!