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

如何在ESM模块中使用vm.runInThisContext运行CommonJS代码?

解决方案

方法1:手动注入require到VM上下文

在ESM环境中,全局作用域没有内置require,但可以通过node:module模块的createRequire方法生成符合CommonJS规范的require函数,再将它注入到VM执行的上下文中。

示例代码:

import vm from "node:vm";
import { createRequire } from "node:module";

// 创建当前ESM模块对应的require函数
const require = createRequire(import.meta.url);

// 定义待执行的CommonJS代码
const code = `
  const path = require("path");
  console.log(path.resolve("test.mjs"));
`;

// 创建VM上下文并注入require
const context = vm.createContext({ require });
// 编译代码并在指定上下文执行
const script = new vm.Script(code);
script.runInContext(context);

方法2:使用runInNewContext直接传入上下文

简化写法,直接通过vm.runInNewContext将包含require的上下文传入:

import vm from "node:vm";
import { createRequire } from "node:module";

const require = createRequire(import.meta.url);
const code = `
  require("path").resolve("test.mjs");
`;

// 直接传入包含require的上下文对象
vm.runInNewContext(code, { require });

方法3:模拟完整CommonJS模块环境

如果待执行代码依赖module、exports、__dirname等CommonJS变量,可以注入这些变量以实现更完整的兼容:

import vm from "node:vm";
import { createRequire } from "node:module";
import { fileURLToPath } from "node:url";
import { dirname } from "node:path";

const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const require = createRequire(import.meta.url);
const module = { exports: {} };
const exports = module.exports;

const context = vm.createContext({
  require,
  module,
  exports,
  __filename,
  __dirname
});

const code = `
  const path = require("path");
  module.exports.resolvedPath = path.resolve(__dirname, "test.mjs");
`;

const script = new vm.Script(code);
script.runInContext(context);

// 获取执行后导出的内容
console.log(context.module.exports.resolvedPath);

关键说明

  • createRequire(import.meta.url)生成的require会以当前ESM模块的路径为基准解析模块,和CommonJS环境下的require行为一致。
  • VM执行的代码默认与当前模块作用域隔离,必须显式注入需要的变量才能在代码中使用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 04:33:28