在 vm 脚本上下文中传递函数

Pass functions in a vm script context

本文关键字:传递函数 上下文 脚本 vm      更新时间:2023-09-26

假设我有一个看起来像这样的库模块:

module.exports = {
    increment: function() {
         count++;
    }
}

我想在动态生成的脚本中使用它,如下所示:

(function() { lib.increment(); })();

通过在沙盒中传递它:

var sandbox = {
    count: 1
    lib: require('./lib')
}
var script = new vm.Script('(function() { lib.increment() })();');
script.runInNewContext(sandbox);

遇到的明显问题是,一方面我不能要求"lib",因为"count"没有在lib中定义.js;另一方面,如果我在"lib.js"文件的导出上方定义var count,这个新的count变量将受到影响,而不是沙箱中的变量。

以下是我想遵守的约束:

  • 在生成的文件上使用 vm 而不是 eval() 或 require()
  • 在外部文件中定义"lib"
  • 无需修改自动生成的脚本,因此不使用lib.increment.apply(context)或类似内容

到目前为止,我找到的唯一解决方案是在生成的脚本中将lib函数作为字符串预置,或者直接在sandbox对象上定义它们,我认为这是一个不太理想的选择。

似乎没有任何方法可以在require调用中传递变量的上下文。

实现

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

库.js

module.exports = function(context) {
  var count = context.count;
  return {
    increment: function() {
      count++;
    }
  };
};

主.js

var sandbox = {
  count: 1
};
sandbox.lib = require('./lib')(sandbox);
var script = new vm.Script('(function() { lib.increment() })();');
script.runInNewContext(sandbox);