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

如何在通过GraalVM从Java程序调用的JavaScript中使用import语句

问题根因

GraalJS默认将eval传入的JS代码识别为传统脚本(Script),而import/export是ES模块(ESM)的专属语法,只有在模块模式下才会被解析,所以直接传带import的代码会报语法错误。

正确实现步骤

第一步:创建Context时开启ES模块相关配置

import org.graalvm.polyglot.Context;
import org.graalvm.polyglot.Source;

// 初始化Context时添加必要配置
Context context = Context.newBuilder("js")
        // 开启ES模块支持
        .option("js.esm-eval-returns-exports", "true")
        // 允许访问本地文件系统用于加载模块
        .allowIO(true)
        // 可选:如果要加载npm安装的依赖,配置node_modules的路径
        .option("js.commonjs-require", "true")
        .option("js.commonjs-require-cwd", "/path/to/your/project/root") // 这里填你存放node_modules的目录路径
        .build();

第二步:两种执行带import代码的方式

方式1:直接执行ESM代码

不要直接传字符串给eval,先构造Source对象,明确指定这是ES模块:

Source esmSource = Source.newBuilder("js", "import v4 from 'uuid';var o = v4();", "my-esm-script.js")
        // 标记为ES模块
        .mimeType("application/javascript+module")
        .build();
context.eval(esmSource);

// 如果需要获取JS模块导出的变量可参考以下写法
Source exportSource = Source.newBuilder("js", "import v4 from 'uuid';export const uuid = v4();", "export-script.js")
        .mimeType("application/javascript+module")
        .build();
var exports = context.eval(exportSource);
String uuid = exports.getMember("uuid").asString();

方式2:加载独立的JS模块文件

直接用Source加载文件,不需要手动读取文件流:

// 直接从资源路径加载js模块文件
Source scriptSource = Source.newBuilder("js", Controller.class.getResource("/script.js"))
        .mimeType("application/javascript+module")
        .build();
context.eval(scriptSource);

注意事项

  • 如果你使用的是npm安装的uuid包,要确保配置的js.commonjs-require-cwd目录下存在node_modules/uuid文件夹,否则会报模块找不到的错误
  • GraalJS版本建议使用22.3及以上的稳定版,旧版本的ESM支持存在较多兼容性问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 09:36:02