Node.js虚拟环境

有时候代码中会允许用户提交一小段js代码并返回运行结果, 例如在模版配置中允许用户选择几个内置参数配置一个字符串
就像main/java/{packagePath}/database/service/{customClassName}Service.java 允许用户配置自定义文件路径, 其中packagePathcustomClassName… 是内置对象

要实现这个功能

  • 其中一种方法就是直接字符串替换, 但是有点不严谨, 例如用户正好需要输入字符串"{customClassName}" 那就出现问题了, 就需要再考虑转义的问题
  • 另一种方法就是使用eval(), 但是直接执行用户提交的脚本是有风险的, 这里就可以用到虚拟环境, Node.js自带的vm
1
2
3
4
5
6
7
8
9
10
11
12
const vm = require('vm');

let data = {
customClassName:"TestClass",
packagePath:"com/a/b/c",
className:"MainClass",
//...
};
let format = "main/java/${packagePath}/database/service/${customClassName}Service.java";
vm.createContext(data);
let value = vm.runInContext("`" + format + "`", data);
console.log(value);

使用执行脚本的方式避免了前面转义的问题, 而且极大扩充了自定义性, 用户可以在${customClassName}中调用js原生的字符串操作函数

这里提供了一种虚拟环境的使用场景, 但是即使在虚拟环境下也不建议运行不信任的脚本