使用 runInThisContext 在 ESM 模块中运行 CommonJS 代码

问题描述 投票:0回答:1

第三方依赖项返回一个 javascript 代码,我想使用

vm.runInThisContext
来执行该代码。

不幸的是,javascript 模块系统不匹配,因为我的脚本必须是 EcmaScriptModule,并且生成的 javascript 代码只能生成为 CommonJs。

我尝试了

runInThisContext
的不同选项,但无法使其工作。

这是我的问题的简化版本:

示例.mjs

import vm from "node:vm";

// Code to be executed
const code = `
  require("path").resolve("test.mjs");
`;

// Execute code in the current context
vm.runInThisContext(code);
node test.mjs

evalmachine.<anonymous>:2
  require("path").resolve("test.mjs");
  ^

ReferenceError: require is not defined
    at evalmachine.<anonymous>:2:3
    at Script.runInThisContext (node:vm:129:12)
    at Object.runInThisContext (node:vm:307:38)
    at test.mjs:9:4
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)

这个跨模块问题有什么解决办法吗?

javascript node.js ecmascript-6 commonjs
1个回答
0
投票

我认为您不能使用

runInThisContext
,因为它仍然与您的全局
esm
模块加载器绑定在一起,相反,您可以使用
runInNewContext
并提供 CommonJS 模块加载器的单独沙盒版本。

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

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const require = createRequire(import.meta.url);

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

const sandbox = {
  require,
  __dirname,
  console,
};

vm.runInNewContext(code, sandbox);

runInNewContext

工作示例

© www.soinside.com 2019 - 2024. All rights reserved.