vm和vm2 实现nodejs 沙盒环境
vm (Virtual Machine)是 Node.js 顶级模块之一,vm 模块可以在 V8 虚拟机的独立上下文-运行时环境中编译和执行 JavaScript 代码,防止代码对系统产生不可预知的影响。
Node.js使用V8 JavaScript引擎作为实际执行环境,并使用vm和vm2模块实现沙盒环境。V8引擎负责将JavaScript代码转换为机器语言,而vm和vm2则用于创建一个新的JavaScript上下文,以便隔离其他JavaScript代码的影响。
通过vm和vm2可以实现对代码片段的执行,但不会对其他代码产生影响。因此,可以将不同的应用程序都运行在各自独立的沙盒中,而不会影响到其他应用程序。
vm机制是不安全的,官方不建议用它来执行不安全的代码(相比 eval、Function 更安全,简单)。
vm2
const vm = require('vm2').VM; // Create a new VM with a sandbox const sandbox = { name: 'Alice' }; const vmInstance = new vm({ sandbox }); // Run some code in the sandbox const code = ` function greet() { return 'Hello, ' + name + '!'; } greet(); `; const result = vmInstance.run(code); console.log(result); // "Hello, Alice!"
使用 vm
创建沙盒环境的好处是它可以提供独立的运行环境,可以防止代码对系统产生不可预知的影响。 通过在运行时传递一个沙盒对象,可以设置沙盒环境中可以使用的全局变量和函数。
使用 eval
创建沙盒环境(比如微前端场景)的方式主要是使用某些方法来阻止 eval 访问全局作用域,比如使用 "with(new Proxy({}, {get: function(){return eval}}))" 将 eval 封装在局部作用域中,防止访问全局变量。但这种方式并不保证完全安全,并且运行速度慢于 vm.
总结,使用 vm 是更加安全的方式,并且能够更好的控制环境,运行速度更快。而 eval 存在较大的安全风险,并且难以控制 。 当然前提是nodejs 环境下。