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

NodeJS:能否向isolated-vm的Isolate传递第三方模块?

问题描述

我尝试在isolated-vm的Isolate中执行脚本代码,该脚本需要lodash、node-xlsx等第三方包作为依赖。请问能否将这些依赖模块传递给Isolate?

尝试传递模块时出现以下错误:

TypeError: [object Module] could not be cloned.

代码示例:

import ivm from 'isolated-vm'
import _ from 'lodash-es'

(async function() {
        try{
                let code = `
                        async function setup() {
                                log('setup called!!');
                                log('config -> ', config);
                        }
                        setup();
                `;
                const isolate = new ivm.Isolate({ memoryLimit: 128 })
                const context = isolate.createContextSync()

                const jail = context.global
                jail.setSync('global', jail.derefInto());

                const config = {
                        id: 1234,
                        name: 'test'
                }
                jail.setSync('config', new ivm.ExternalCopy(config).copyInto());

                jail.setSync('libraries', new ivm.ExternalCopy(_).copyInto());

                jail.setSync('log', function(...args) {
                        console.log(...args);
                })

                const hostile = isolate.compileScriptSync(code)
                hostile.run(context).catch(err => console.error(err));

                
        } catch(e) {
                console.log('err->', e)
        }
        
}) ()

期望:能够在setup()函数中访问libraries(即lodash模块)的内容


解决方案

报错原因

isolated-vm的ExternalCopy仅支持克隆可序列化的值(如原始类型、普通对象、数组,以及部分可转移对象)。你导入的_是ES模块对象,这类对象包含模块元数据、内部引用等不可序列化的内容,因此无法直接通过ExternalCopy传递。

可行解决方法

1. 传递模块的导出内容而非整个模块对象

对于ES模块(比如lodash-es),实际工具函数都在它的default导出中。提取这部分内容传递给Isolate即可:

修改代码中传递lodash的部分:

// 替换原有的模块对象传递代码
jail.setSync('libraries', new ivm.ExternalCopy(_.default).copyInto());

之后在隔离脚本中可正常调用lodash方法:

let code = `
        async function setup() {
                log('setup called!!');
                log('config -> ', config);
                // 使用lodash的map方法
                log('lodash map test: ', libraries.map([1,2,3], n => n*2));
        }
        setup();
`;

2. 在Isolate内部直接加载模块

如果Isolate配置允许访问文件系统,可在隔离环境内直接加载第三方模块,无需从外部传递。

示例:使用compileModule编译ES模块脚本

const moduleCode = `
        import _ from 'lodash-es';
        export async function setup() {
                log('setup called!!');
                log('lodash version: ', _.VERSION);
        }
`;

const module = await isolate.compileModule(moduleCode);
module.instantiate(context, (specifier) => {
        // 处理模块解析,返回对应模块的导出
        if (specifier === 'lodash-es') {
                return ivm.Reference.from(_.default);
        }
        throw new Error(`Unsupported module: ${specifier}`);
});

await module.evaluate();
const setup = module.namespace.getSync('setup');
await setup.call(context);

3. 手动提取需要的模块部分

如果仅需模块中的特定函数或对象,可手动提取后传递,避免传递整个模块:

// 只传递lodash的map和get方法
const neededLodash = { map: _.default.map, get: _.default.get };
jail.setSync('libraries', new ivm.ExternalCopy(neededLodash).copyInto());

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 01:27:57