上手
JavaScript 上手
准备
JS 插件需要我们打过补丁的 ComponentizeJS(原因见语言选择)。 模板里已经配好,只需要本机有 Node 与 Rust:
rustup target add wasm32-wasip1 # npm 安装 git 依赖时要现场构建 splicergit clone --recurse-submodules https://github.com/AstralSightStudios/AstroBox-NG-Plugin-Template-JS
cd AstroBox-NG-Plugin-Template-JS
npm install写插件
导出对象名对应 WIT 里的接口名(lifecycle / event):
import { arch, platform } from 'astrobox:psys-host-v4/os';
import { render, getRenderSize, Element } from 'astrobox:psys-host-v4/ui';
export const lifecycle = {
async onLoad() {
console.log(`hello from ${platform()}/${arch()}`);
},
};
export const event = {
async onEvent(eventType, payload) { return ''; },
async onUiEvent(eventId, uiEvent, payload) { return ''; },
async onUiRender(elementId) {
const size = getRenderSize();
const root = new Element('div', null).flex();
render(elementId, root.child(new Element('p', `${size.width}px`)));
},
async onCardRender(cardId) {},
};两个容易踩的点
WIT 的 enum 在 JS 里是字符串。 没有 ElementType.DIV 这种东西:
new Element('div', 'text') // ✅
new Element(ElementType.DIV, ...) // ❌ 会报 doesn't provide an export named 'ElementType'宿主接口是同步调用的。 虽然 WIT 里写着 async func,但被同步 lower 了,
JS 侧直接当普通函数用,调用期间线程阻塞到宿主返回:
const size = getRenderSize(); // 不需要 await导出函数可以是 async,引擎会在返回前把 Promise 结算掉。
构建
npm run build # -> dist/plugin.wasm
npm run package # 顺便打 .abp产物约 14 MB(内嵌 SpiderMonkey)。宿主首次加载会预编译并缓存。