javascript - 替代节点脚本中的 eval()
问题描述
我正在编写一个脚本,该脚本在我们之前在 Jenkins 的构建过程中运行npm install
。我的问题是我需要从外部资源下载一个 JavaScript 文件并从中读取一个变量。
unzipper.on('extract', () => {
const content = fs.readFileSync(`${outputDir}/js/en.js`, 'utf8');
eval(content); // Less smellier alternative?
if (obj) {
const str = JSON.stringify(obj);
fs.writeFileSync(`${outputDir}/public/data.json`, str);
} else {
throw 'Variable `obj` not found';
}
});
我知道“eval
是邪恶的”,但我在网上找到的任何建议的替代方案似乎都不起作用。我尝试了不同的变体new Function(obj)()
,但 Node 似乎在之后退出脚本(if
-case 永远不会运行)。
想法?
解决方案
由于 node.js 提供了直接与 V8 运行器对话的API,因此使用它可能是一个好主意。基本上,它是节点底层使用的 API require
。
假设有问题的 js 文件包含我们感兴趣的变量obj
,我们执行以下操作:
- 从文件中读取代码
- 附加
; obj
到代码以确保它是它评估的最后一个表达式 - 将代码传递给 V8 进行评估
- 获取返回值(这是我们的
obj
):
const fs = require('fs'),
vm = require('vm');
const code = fs.readFileSync('path-to-js-file', 'utf8');
const obj = vm.runInNewContext(code + ';obj');
推荐阅读
- android - TensorFlowInferenceInterface 返回低值
- ios - UIView transform.scaleBy 动画不起作用
- c++11 - 使用值作为结构数据类型更新 std::map
- javascript - 用php自动填充html表单
- f# - 检索报价中的 F# 代码
- javascript - 如何从 momentjs 对象中提取日期和时间并将它们加入形成新的时刻对象?
- javascript - 为什么这个循环在 99999 处停止
- wordpress - 将字段添加到自定义 WP 登录表单
- python - Python 与 UDP BitTorrent 跟踪器建立连接
- python - 状态栏上的 wxpython SetStatusText 不起作用