使用VM模块运行Node.js脚本:" ReferenceError:require不是函数"

时间:2016-10-25 08:28:45

标签: node.js virtual-machine require

我正在编写自己的自定义node.js服务器。它现在处理静态页面,AJAX GET,POST和OPTIONS请求(后者用于CORS),但我知道我选择用于运行服务器端GET和POST脚本的方法并不是最佳的 - 官方node.js文档声明启动众多子node.js进程是一个坏主意,因为它是一种资源匮乏的方法。它有效,但我知道可能有更好的方法来实现相同的结果。

所以,我下了VM模块。我的第一个想法是,这将解决使用子进程混乱机器的问题,并使我的服务器更具可扩展性。

有一个小问题。我的服务器端脚本,用于目录列表和放大器等任务。将结果发送回浏览器,从几个 require 语句开始加载所需的模块。

最后编写代码来读取脚本文件,并将其传递给vm.Script(),我现在遇到一个错误:

" ReferenceError:require不是函数"

我自从了解到这一点之后,就是VM为脚本启动了一个裸V8执行环境,而不是一个独立的node.js执行环境。为了使我的想法有效,我需要VM为我提供一个单独的沙盒node.js执行环境。我如何实现这一目标?

我的初步研究告诉我,我需要为VM执行环境提供自己独立的node.js全局副本,以便需要功能。我的理解是正确的吗?如果是这样,我需要采取哪些步骤来执行此任务?

1 个答案:

答案 0 :(得分:4)

  

我的初步研究告诉我,我需要为VM执行环境提供自己独立的node.js全局变量副本,因此需要按预期的功能

这对于runInNewContext来说是正确的,它不会与“父”上下文共享全局变量(而不是runInThisContext)。

要在脚本中提供require的功能,您可以将其作为函数传递。其他本地人也是如此,例如console

const vm = require('vm');

let sandbox = {
  require,
  console
};

vm.runInNewContext(`

let util = require('util');
console.log(util.inspect(util));

`, sandbox);

除了直接传递require,您还可以传递一个函数,即 - 实现模块白名单(这样您就可以控制允许脚本加载哪些模块)。