Работа с WebAssembly и Kotlin: от А до Я

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Введение: Почему WebAssembly и Kotlin — идеальная пара

Современная веб-разработка требует не только скорости, но и безопасности. WebAssembly (Wasm) — это низкоуровневый бинарный формат, который выполняется в браузере со скоростью, близкой к нативной. Kotlin, в свою очередь, — это современный мультиплатформенный язык, который компилируется в байт-код JVM, JavaScript и, с недавнего времени, в WebAssembly.

Сочетание Kotlin и WebAssembly открывает новые горизонты: вы можете писать сложную логику на знакомом языке с мощной системой типов, а затем запускать её в любом современном браузере без оверхэда JavaScript. В этой статье мы разберём работу с WebAssembly и Kotlin от А до Я: от установки инструментов до развёртывания готового приложения.

1. Настройка окружения для Kotlin/Wasm

Прежде чем писать код, необходимо подготовить среду. На момент написания статьи официальная поддержка Kotlin/Wasm находится в стадии эксперимента (начиная с Kotlin 1.9.20). Для работы потребуется:

  • JDK 11 или выше (рекомендуется JDK 17)
  • IntelliJ IDEA (Community Edition подойдёт) или любой редактор с поддержкой Gradle
  • Последняя версия Kotlin (1.9.22+).

Создание проекта

Создадим новый проект Gradle с мультиплатформенной конфигурацией. В файле build.gradle.kts укажите плагины и цель Wasm:

plugins {
    kotlin("multiplatform") version "1.9.22"
    kotlin("plugin.serialization") version "1.9.22" // опционально
}

kotlin {
    wasmJs {
        binaries.executable()
        nodejs()
        browser {
            commonWebpackConfig {
                cssSupport {
                    enabled.set(true)
                }
            }
        }
    }

    sourceSets {
        val commonMain by getting
        val wasmJsMain by getting {
            dependencies {
                implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.7.3")
            }
        }
    }
}

После синхронизации Gradle, структура проекта будет готова к компиляции в Wasm.

2. Пишем первую программу на Kotlin/Wasm

Создадим простой модуль, который вычисляет факториал числа — идеальный пример для демонстрации производительности Wasm.

Код на Kotlin

В папке src/wasmJsMain/kotlin создайте файл Main.kt:

import kotlinx.coroutines.*

// Функция, которая будет экспортирована в Wasm
@WasmExport
fun factorial(n: Int): Long {
    if (n < 0) return -1L
    var result = 1L
    for (i in 2..n) {
        result *= i
    }
    return result
}

// Точка входа для браузера
fun main() {
    println("Kotlin/Wasm загружен!")
    // Используем корутины для асинхронного вызова
    GlobalScope.launch {
        val result = factorial(10)
        println("Факториал 10: $result")
    }
}

Аннотация @WasmExport делает функцию доступной из JavaScript. Обратите внимание: не все типы Kotlin можно экспортировать — поддерживаются примитивы, строки и массивы.

Сборка и запуск

Выполните команду Gradle:

./gradlew wasmJsBrowserDevelopmentRun

После сборки откроется браузер с консолью, где вы увидите вывод. Если всё прошло успешно, вы только что запустили Kotlin в WebAssembly!

3. Взаимодействие с JavaScript: мост между двумя мирами

Одна из ключевых возможностей Kotlin/Wasm — двустороннее взаимодействие с JavaScript. Вы можете вызывать JS-функции из Kotlin и наоборот.

Вызов JavaScript из Kotlin

Добавим в Main.kt код, который использует DOM API браузера:

import org.w3c.dom.*

@WasmExport
fun showAlert(message: String) {
    // Используем глобальный объект window
    window.alert("Kotlin говорит: $message")
}

fun main() {
    // Получаем элемент по ID и меняем его содержимое
    val element = document.getElementById("output")
    element?.innerHTML = "Привет из Kotlin/Wasm!"
}

Для этого в build.gradle.kts нужно добавить зависимость kotlin-stdlib-js (она обычно включена по умолчанию для wasmJs).

Вызов Kotlin из JavaScript

После компиляции сгенерируется файл .wasm и JS-обёртка. В HTML-файле подключите скрипт и вызывайте экспортированные функции:

<!DOCTYPE html>
<html>
<head>
    <title>Kotlin Wasm Demo</title>
</head>
<body>
    <div id="output"></div>
    <button onclick="callKotlin()">Вызвать Kotlin</button>

    <script src="build/developmentExecutable/main.js"></script>
    <script>
        async function callKotlin() {
            // Функция была экспортирована через @WasmExport
            const result = await window.factorial(5);
            console.log("Результат из Wasm:", result);
        }
    </script>
</body>
</html>

Обратите внимание: вызовы к Wasm-функциям асинхронны, так как модуль загружается динамически.

4. Оптимизация и продакшн-сборка

Для реальных проектов важно настроить финальную сборку. Используйте команду:

./gradlew wasmJsBrowserDistribution

В папке build/dist/wasmJs/productionExecutable появятся оптимизированные файлы:

  • main.wasm — бинарный модуль
  • main.js — загрузчик и обёртка
  • index.html — точка входа

Советы по оптимизации