Learn · guides
编写您的第一个 GraalVM JavaScript 脚本 (2026)
编写你的第一个 GraalVM JavaScript 脚本:注册入口点,钩住事件,并在不重新编译 Java 的情况下实现热重载。附带一个可运行的示例.
编写您的第一个 GraalVM JavaScript 脚本
编写第一个 GraalVM JavaScript 脚本包含三个小步骤:将脚本与宿主程序的入口点注册,将其附加到事件或模块,并将脚本保存到脚本文件夹中,以便引擎加载它。 引擎运行在 GraalVM Polyglot API 上,因此脚本是真正的 JavaScript,无需重新编译任何 Java 代码即可重新加载.
首先你需要
一个宿主程序,其中嵌入了引擎。宿主程序自带 GraalVM JavaScript,暴露了一组供脚本调用的对象,并监视一个脚本文件夹。你不需要自行安装 GraalVM;宿主程序已经将其打包。你只需要编写针对宿主程序提供对象的纯 JavaScript 代码即可。
了解这些对象所映射的内容会有所帮助,但你无需编写任何 Java 代码即可开始。如果你之前写过 JavaScript,那么这种模式会让你感到熟悉:宿主程序就像一个你导入的库,你可以用它来访问程序的内部机制。
三个步骤
找到脚本文件夹
主机启动时从已知的目录加载脚本。请查阅主机文档以获取确切路径。通常,它位于安装目录下的
scripts/文件夹中.创建脚本文件
在那文件夹中创建一个新的
.js文件。 主机在下次加载脚本时会将其拾取,无论是在启动时还是在支持的情况下运行重新加载命令时.注册并连接
在文件中,将脚本与宿主程序的入口点注册,然后将行为附加到事件上,或定义宿主程序能够识别的模块.
就是这样。保存文件,重新加载,脚本就运行了。无需构建步骤,无需编译,无需等待。只需编辑和重新加载。
一个最小示例
大多数宿主提供一个入口点脚本来注册自身,以及几个代理对象,这些对象连接 JavaScript 和程序。确切的名称取决于宿主,但结构是相同的。一个初始脚本通常只是宣告自身并响应一个事件:
// 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 宿主访问白名单声明脚本可以访问哪些类和方法,默认情况下是拒绝的。这保证了脚本的安全性和可预测性。如果你想要的对象没有暴露,宿主必须添加它;你不能从脚本端绕过白名单.
这是一种特性,而不是一个错误。这意味着脚本无法意外地(或恶意地)通过调用内部方法或访问它们不应该访问的对象来破坏宿主程序。这也意味着宿主程序的维护者可以清晰地控制哪些功能是支持的,哪些是不支持的。
常见问题解答
不,宿主程序会捆绑 GraalVM 和它的 JavaScript 引擎。你只需要编写 JavaScript 文件,然后把它放到脚本文件夹里就可以了.
是的。引擎支持最新的 ECMAScript 特性,包括使用 import 和 export 的模块,因此您不会被困在旧的子集中.
检查文件是否位于宿主脚本文件夹中,是否具有宿主所期望的扩展名,以及是否已在宿主的入口点注册。 注册调用中的拼写错误通常是原因.
不,引擎是嵌入在宿主 JVM 内部的,所以你的脚本与宿主程序交互,而不是与独立的 Node.js 运行时环境交互.