导航
对于 Node.js 而言, 正常情况下只有一个上下文, 甚至于内置的很多方面例如 require 的实现只是在启动的时候运行了内置的函数.
默认情况下没有“完全独立”的上下文: 虽然 Node.js 的每个文件(模块)看起来是独立的,但那是 Node.js 在加载时通过一个包装函数(Wrapper)实现的。实际上,所有代码都运行在同一个 VM(虚拟机)上下文中。如果你在某个文件中直接定义全局变量(如不使用 var/let/const 直接写 t = 111),它会污染全局作用域(global),从而影响到其他模块。
利用 vm 模块创建“真沙盒”: Node.js 提供了 vm 模块,允许开发者创建一个全新的、隔离的上下文。在这种环境下执行的代码不会污染主进程的全局变量,这在执行不受信任的第三方代码时非常有用。
'use strict';
const vm = require('vm');
let code =
`(function(require) {
const http = require('http');
http.createServer( (request, response) => {
response.writeHead(200, {'Content-Type': 'text/plain'});
response.end('Hello World\\\\n');
}).listen(8124);
console.log('Server running at <http://127.0.0.1:8124/>');
})`;
vm.runInThisContext(code)(require);
这种执行方式与 eval 和 Function 有明显的区别. 关于 VM 更多的一些接口可以先阅读官方文档 VM (虚拟机)
主要原因在于性能开销和内存管理:
Node.js 选择通过**函数包装器(Function Wrapper)**这种低成本的方式来实现模块级别的伪作用域隔离,这在保证了开发便捷性(通过 require/exports 通信)的同时,兼顾了极致的运行性能。