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

Pie*_*aud 3 javascript v8 node.js

假设我有一个如下所示的库模块:

\n\n
module.exports = {\n    increment: function() {\n         count++;\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n
(function() { lib.increment(); })();\n
Run Code Online (Sandbox Code Playgroud)\n\n

通过将其传递到沙箱中:

\n\n
var sandbox = {\n    count: 1\n    lib: require(\'./lib\')\n}\nvar script = new vm.Script(\'(function() { lib.increment() })();\');\nscript.runInNewContext(sandbox);\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

以下是我希望遵守的限制:

\n\n
    \n
  • 在生成的文件上使用 vm 而不是 eval() 或 require()
  • \n
  • 在外部文件中定义“lib”
  • \n
  • 没有修改自动生成的脚本,所以没有使用lib.increment.apply(context)或类似
  • \n
\n\n

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

\n\n

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

\n

Mik*_*uck 5

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

库.js

module.exports = function(context) {
  var count = context.count;
  return {
    increment: function() {
      count++;
    }
  };
};
Run Code Online (Sandbox Code Playgroud)

main.js

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