Перейти до вмісту

WebImage: з JVM у WebAssembly

Компілюйте Java або Kotlin у модуль WebAssembly із завантажувачем на JavaScript за допомогою артефакту WebImage в Elide: вимоги, бекенди, хости й параметри компілятора.

На цій сторінці

Артефакт WebImage компілює байт-код JVM у завантажувач на JavaScript і модуль WASM. Як запустити наявний бінарний файл WASM або WASI, описано на сторінці WebAssembly.

Вимоги

  • Binaryen 119 або новіший, з wasm-as у PATH під час збирання.
  • Код, що відповідає вимогам Native Image: метадані досяжності для рефлексії, ресурсів і проксі; жодних нативних залежностей.
  • Хост з обробкою винятків WASM (і WASM GC для wasm-gc): Node.js 25+ або сучасний браузер.

Розгорнутому бандлу не потрібні ні Elide, ні Binaryen.

Збирання повного проєкту

hello-wasm/
  elide.pkl
  src/main/java/Hello.java
public class Hello {
  public static void main(String[] args) {
    System.out.println("Hello from WebImage");
  }
}
amends "elide:project.pkl"
import "elide:Jvm.pkl" as jvm
import "elide:NativeImage.pkl" as nativeImage

name = "hello-wasm"

artifacts {
  ["app-jar"] = new jvm.Jar {
    sources { "main" }
  }
  ["web"] = new nativeImage.WebImage {
    from { "app-jar" }
    name = "hello"
    entrypoint = "Hello"
    backend = "wasm-gc"
    runtime = "generic"
    autoRun = true
    sourceMap = false
    options {
      optimization = "b"
    }
  }
}
elide build

Elide збирає app-jar, потім компілює його у web. name — базова назва без .js і .wasm; optimization = "b" — режим швидкого збирання. Результат записується в .dev/artifacts/native-image/:

ФайлПризначення
hello.jsЗавантажувач на JavaScript і точка входу.
hello.js.wasmМодуль WASM, який завантажує hello.js.
hello.js.watТекстова форма WASM для перегляду.
hello.js.mapМапа вихідного коду для завантажувача, якщо sourceMap = true.

Розгортайте hello.js і hello.js.wasm разом. Kotlin та інші мови JVM працюють так само, якщо їх запаковано в JAR. Влучання в кеш відновлює весь бандл; вимкнення sourceMap видаляє старий .js.map.

Вибір бекенда й хоста

ВластивістьЗначенняЗміст
backend"wasm-gc" (за замовчуванням)Використовує збирач сміття WASM хоста.
backend"wasm-lm"Використовує збирач сміття в лінійній пам’яті; завантажувач однаково потрібен, це не бінарний файл WASI.
runtime"generic" (за замовчуванням)Завантажувач підтримує браузери й Node.
runtime"browser"Завантажувач, спеціалізований для браузерів.
runtime"node"Завантажувач, спеціалізований для API, сумісних із Node.
autoRuntrue (за замовчуванням)Запускає програму, щойно завантажувач завантажено; false залишає запуск сторінці, що його вбудовує.
sourceMapfalse (за замовчуванням)true створює hello.js.map.

Точка входу обов’язкова навіть з autoRun = false. Жодне значення runtime не призначене для Cloudflare Workers, Fastly Compute чи WASI. Спільні поля (from, entrypoint, moduleName, options) описано в розділі Native Image. WebImage не може бути входом артефакту для контейнера.

Посібники для цілей: Browser WASM і Edge WASM.

Запуск на серверному хості

З runtime = "generic" або "node":

node .dev/artifacts/native-image/hello.js
Hello from WebImage

Запуск у браузері

З runtime = "browser" або "generic" і autoRun = true покладіть цей index.html у .dev/artifacts/native-image/:

<!doctype html>
<html lang="en">
  <meta charset="utf-8" />
  <title>Hello WebImage</title>
  <body>
    <p>Open the browser console to see the application output.</p>
    <script src="./hello.js"></script>
  </body>
</html>
elide dev --no-tui --port 8000 .dev/artifacts/native-image

Відкрийте http://localhost:8000/; вивід з’явиться в консолі браузера. URL-адреси file:// не працюють.

Параметри компілятора

Блок options артефакту приймає параметри компілятора Native Image; які з них діють, залежить від бекенда. Два випадки стосуються лише WebImage:

  • options.driverMode = "external" використовує native-image з GRAALVM_HOME або JAVA_HOME; це встановлення має підтримувати бекенди WebAssembly.
  • -H:EntryPointsConfig=config/entrypoints.json в options.flags задає точки входу; шлях вказується відносно кореня проєкту, а зміна файлу запускає повторне збирання.

Компіляція без маніфесту проєкту

elide javac -- -d classes src/main/java/Hello.java
elide native-image -- --tool:wasm-gc -Ob -cp classes -o hello Hello
elide native-image -- --tool:wasm-lm -Ob -cp classes -o hello-lm Hello

Бандли записуються в поточний каталог. Артефакт NativeImage з --tool:wasm-gc або --tool:wasm-lm в options.flags і далі збирається. Щоб перевести його на новий вигляд, замініть клас на WebImage, приберіть прапорець і type, якщо він є, і задайте backend.

Усунення несправностей

СимптомРозв’язання
wasm-as не знайденоВстановіть Binaryen і додайте його до PATH збирання.
Зовнішній драйвер відхиляє бекенд WebAssemblyВкажіть у GRAALVM_HOME або JAVA_HOME встановлення, чий native-image його підтримує, або використайте driverMode = "embedded".
Суперечливі низькорівневі параметриПриберіть прапорці бекенда, середовища виконання, запуску й мапи вихідного коду; використовуйте типізовані властивості. Не перевизначайте Backend і властивість лаунчера.
Хост відхиляє інструкції WASMВикористовуйте хост з обробкою винятків і, для wasm-gc, з WASM GC.
Браузер не може завантажити модульРоздавайте завантажувач і модуль разом через HTTP; перевірте запитувану URL-адресу.
elide run hello.js.wasm повідомляє про відсутні імпортиЗапустіть натомість hello.js; модулю потрібен його завантажувач.

Чи була ця сторінка корисною?