Learn · guides

编写您的第一个 GraalVM JavaScript 脚本 (2026)

编写你的第一个 GraalVM JavaScript 脚本:注册入口点,钩住事件,并在不重新编译 Java 的情况下实现热重载。附带一个可运行的示例.

TRtrolPublished 1 min read

编写您的第一个 GraalVM JavaScript 脚本

编写第一个 GraalVM JavaScript 脚本包含三个小步骤:将脚本与宿主程序的入口点注册,将其附加到事件或模块,并将脚本保存到脚本文件夹中,以便引擎加载它。 引擎运行在 GraalVM Polyglot API 上,因此脚本是真正的 JavaScript,无需重新编译任何 Java 代码即可重新加载.

首先你需要

一个宿主程序,其中嵌入了引擎。宿主程序自带 GraalVM JavaScript,暴露了一组供脚本调用的对象,并监视一个脚本文件夹。你不需要自行安装 GraalVM;宿主程序已经将其打包。你只需要编写针对宿主程序提供对象的纯 JavaScript 代码即可。

了解这些对象所映射的内容会有所帮助,但你无需编写任何 Java 代码即可开始。如果你之前写过 JavaScript,那么这种模式会让你感到熟悉:宿主程序就像一个你导入的库,你可以用它来访问程序的内部机制。

三个步骤

  1. 找到脚本文件夹

    主机启动时从已知的目录加载脚本。请查阅主机文档以获取确切路径。通常,它位于安装目录下的 scripts/ 文件夹中.

  2. 创建脚本文件

    在那文件夹中创建一个新的 .js 文件。 主机在下次加载脚本时会将其拾取,无论是在启动时还是在支持的情况下运行重新加载命令时.

  3. 注册并连接

    在文件中,将脚本与宿主程序的入口点注册,然后将行为附加到事件上,或定义宿主程序能够识别的模块.

就是这样。保存文件,重新加载,脚本就运行了。无需构建步骤,无需编译,无需等待。只需编辑和重新加载。

一个最小示例

大多数宿主提供一个入口点脚本来注册自身,以及几个代理对象,这些对象连接 JavaScript 和程序。确切的名称取决于宿主,但结构是相同的。一个初始脚本通常只是宣告自身并响应一个事件:

js
// Register the script with the host.
script.register({
  name: "hello-world",
  version: "1.0.0",
});
 
// React to an event the host exposes.
script.on("enable", () => {
  client.print("Hello from my first script.");
});

请阅读宿主自身的 API 参考文档,以获取真实的对象的名称和方法。重点在于模式:注册,然后钩住一个事件或定义一个模块。大多数宿主会暴露一个事件循环或生命周期钩子,并且大多数脚本通常会监听其中一个。

工作时进行热重载

保存文件并重新加载脚本(如果宿主不支持实时重载,则重启宿主)。更改立即生效,无需重建。这个快速循环是使用脚本而不是编译 mod 的主要原因:脚本可以在几秒钟内重新加载,而编译后的 mod 必须重建和重新启动。

方法迭代循环语言适用时机
GraalVM JavaScript 脚本编辑、保存、重新加载JavaScript快速调整、自定义行为
编译后的 mod重建、重新启动Java 或 Kotlin更大的功能、更深入的钩子

如果你只是添加一个简单的功能或调整行为,那么脚本是最佳选择。如果你需要深度集成引擎或暴露新的原件,那么编译的模组可能更有意义。

脚本能做什么,不能做什么

脚本只能调用宿主暴露的对象,除此之外不行。宿主通过 GraalVM Polyglot 宿主访问白名单声明脚本可以访问哪些类和方法,默认情况下是拒绝的。这保证了脚本的安全性和可预测性。如果你想要的对象没有暴露,宿主必须添加它;你不能从脚本端绕过白名单.

这是一种特性,而不是一个错误。这意味着脚本无法意外地(或恶意地)通过调用内部方法或访问它们不应该访问的对象来破坏宿主程序。这也意味着宿主程序的维护者可以清晰地控制哪些功能是支持的,哪些是不支持的。

常见问题解答