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

如何通过v8或deno_core将JavaScript模块成员导出到Rust并调用?

解决deno_core调用ES模块导出函数的问题

你之前的代码找不到sum函数,核心原因是ES模块的导出不会挂载到全局对象,而是保存在模块自身的命名空间对象里。直接从global里查找自然拿不到目标函数。

修正步骤

  1. 模块评估完成后,result.await?会返回模块的命名空间对象,需要保留这个对象
  2. 从模块命名空间中获取导出的sum函数,而非全局对象

修正后的完整代码

use deno_core::{error::Error, JsRuntime, RuntimeOptions, FsModuleLoader};
use std::rc::Rc;
use tokio;
use anyhow::Context;

fn main() -> Result<(), Error> {
    let mut js_runtime = JsRuntime::new(RuntimeOptions {
        module_loader: Some(Rc::new(FsModuleLoader)),
        ..Default::default()
    });

    let runtime = tokio::runtime::Builder::new_current_thread()
        .enable_all()
        .build()?;

    let main_module = deno_core::resolve_path(
        "./module.js",
        &std::env::current_dir().context("Unable to get CWD")?,
    )?;

    let future = async move {
        let mod_id = js_runtime.load_main_module(&main_module, None).await?;
        // 评估模块并获取其命名空间对象
        let module_namespace = js_runtime.mod_evaluate(mod_id).await?;
        
        js_runtime.run_event_loop(false).await?;

        let context = js_runtime.global_context();
        let scope = &mut js_runtime.handle_scope();
        // 将模块命名空间转换为v8可操作的Value
        let ns_value = module_namespace.open(scope);

        let func_key = v8::String::new(scope, "sum").unwrap();
        let func = ns_value.get(scope, func_key.into()).unwrap();

        if func.is_function() {
            println!("func is a function");
            // 可选:调用sum函数示例
            let args = [
                v8::Number::new(scope, 2.0).into(),
                v8::Number::new(scope, 3.0).into(),
            ];
            let result = func.call_as_function(scope, ns_value, &args).unwrap();
            let result_num = result.to_rust_string_lossy(scope);
            println!("sum(2,3) = {}", result_num);
        } else {
            println!("func is not a function but {:?}", func.type_of(scope));
        }

        Ok(())
    };
    runtime.block_on(future)
}

补充说明

  • 确保你的module.js内容正确:
    export function sum(a, b) {
      return a + b;
    }
    
  • 若使用自定义FsModuleLoader,需确保它能正确加载本地模块;使用默认的deno_core::FsModuleLoader则需确认依赖配置正确
  • 模块评估后需调用run_event_loop处理完异步任务(如果存在),false参数表示处理完当前待处理任务后退出事件循环

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 14:22:50