在同一进程中创建“新鲜和空的”Node.js JavaScript 上下文的最佳方法?

Can*_*ure 9 javascript v8 node.js

Node.js 和 v8 专家的问题。

我正在开发Siesta测试工具的新版本。

默认情况下,Siesta 在新创建的 Node.js 进程中运行每个测试。但是,我想避免产生新进程的开销,而是提供在空 JavaScript 上下文中运行测试的能力。

可以使用内置的vm模块创建此类上下文。但是,以这种方式创建的上下文是一个空的JavaScript上下文,而不是一个空的Node.js上下文。例如,它没有全局变量process

> require('vm').runInNewContext('process')
evalmachine.<anonymous>:1
process
^

Uncaught ReferenceError: process is not defined
    at evalmachine.<anonymous>:1:1
    at Script.runInContext (vm.js:143:18)
    at Script.runInNewContext (vm.js:148:17)
    at Object.runInNewContext (vm.js:303:38)
    at REPL30:1:15
    at Script.runInThisContext (vm.js:133:18)
    at REPLServer.defaultEval (repl.js:484:29)
    at bound (domain.js:413:15)
    at REPLServer.runBound [as eval] (domain.js:424:12)
    at REPLServer.onLine (repl.js:817:10)
> 
Run Code Online (Sandbox Code Playgroud)

所以问题是 - 在同一进程中创建一个新的和空的 Node.js 上下文的最佳方法是什么?我期望这样的背景下都定期全局,如processrequire等此外,我预计这种情况下有一个单独的,最初空模块高速缓存,这样即使有些模块在主背景加载,这将是在新的上下文中再次加载。

当然,我可以将全局变量从主上下文映射到新上下文,但这意味着这些全局变量在上下文之间共享,而我的目标是上下文隔离。此外,模块缓存也将被共享。

我相信 JavaScript 和 Node.js 上下文之间的区别在于后者是用某个脚本初始化的。是否有可能以某种方式获取该脚本的来源并在新的上下文中执行它?

谢谢!

tmi*_*lar 0

一种选择是使用'child_process' fork() API,它使用自己的内存和 V8 实例旋转一个新的 Node 进程。然而,这可能与您现在正在做的事情相同或非常相似(至少在理论上)。

请记住,生成的 Node.js 子进程独立于父进程,但两者之间建立的 IPC 通信通道除外。每个进程都有自己的内存和自己的 V8 实例。由于需要额外的资源分配,因此不建议生成大量 Node.js 子进程。

请注意,这个分叉并不是整个运行过程的克隆:

与 fork(2) POSIX 系统调用不同,child_process.fork() 不会克隆当前进程。

另一个看起来很有前途的选项是使用 Node async_hooks API 来模拟独立上下文上的执行。查看node-execution-context,它可能会满足您的要求。