You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从script.runInContext的结果中无损获取AST表示?

解决方案

核心问题原因

JSON.stringify会忽略对象中的函数属性,因此无法通过它获取函数源码;而acorn仅能解析字符串形式的JavaScript代码,不能直接处理JS对象,必须先把对象中的函数转换为源码字符串,再拼接成合法的对象代码文本。


方法1:利用函数toString()提取源码

执行vm得到result后,直接调用函数的toString()方法获取其源码,再手动拼接成目标格式的代码字符串:

const vm = require("vm");
const acorn = require("acorn");

let p = `(function (X) {
  var q = 0;
  for (; q < 5; ) {
    // do some stuff
    anotherfunc = function (a) {
      while (X === "somestring") {
        X += "_";
      }
    };
    q++;
  }
  return { anotherfunc: anotherfunc };
})("some arg");
`;

const script = new vm.Script(p);
const context = vm.createContext({});
const result = script.runInContext(context);

// 提取函数源码
const funcSource = result.anotherfunc.toString();
// 拼接成合法的对象代码字符串(注意属性用逗号而非分号)
const targetCode = `{ 
    anotherfunc: ${funcSource}
}`;

// 传给acorn解析AST
const ast = acorn.parse(targetCode, { ecmaVersion: "latest" });
console.log(ast);

方法2:在vm代码中直接返回函数源码

如果担心toString()返回格式不符合预期,可修改vm中的代码,让它同时返回函数和对应的源码字符串:

let p = `(function (X) {
  var q = 0;
  for (; q < 5; ) {
    // do some stuff
    anotherfunc = function (a) {
      while (X === "somestring") {
        X += "_";
      }
    };
    q++;
  }
  // 同时返回函数和其源码
  return { 
    anotherfunc: anotherfunc,
    anotherfuncSource: anotherfunc.toString()
  };
})("some arg");
`;

// 后续直接使用result.anotherfuncSource拼接代码字符串即可

将结果保存到文件

拿到合法的targetCode后,用Node.js的fs模块即可写入文件:

const fs = require("fs");
// 写入文件
fs.writeFileSync("output.js", targetCode);

关键说明

  • acorn无法直接解析JS对象,必须传入字符串形式的代码文本,这是由其JavaScript解析器的定位决定的。
  • 函数的toString()方法在Node.js环境中通常会返回完整的函数源码(除非代码被压缩或特殊处理),足以满足acorn的解析需求。

内容的提问来源于stack exchange,提问作者younes zeboudj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:02:48