← Cloudflare Workers / workers / runtime-apis / webassembly
Wasm в JavaScript
Wasm можно использовать в Worker, написанном на JavaScript или TypeScript, импортировав модуль Wasm
и создав его экземпляр с помощью WebAssembly.instantiate() ↗. Это можно использовать для ускорения вычислительно затратных операций, не связанных со значительным объёмом операций ввода-вывода.
В этом руководстве показаны основы взаимодействия Wasm и JavaScript.
Простой модуль Wasm
В этом руководстве вы используете WebAssembly Text Format, чтобы создать простой модуль Wasm и разобраться в том, как работают импорты и экспорты. На практике код в этом формате обычно не пишут. Вместо этого используют выбранный язык программирования и компилируют его напрямую в WebAssembly Binary Format (.wasm).
Ознакомьтесь со следующим примером модуля (;; обозначает комментарий):
;; src/simple.wat
(module
;; Import a function from JavaScript named `imported_func`
;; which takes a single i32 argument and assign to
;; variable $i
(func $i (import "imports" "imported_func") (param i32))
;; Export a function named `exported_func` which takes a
;; single i32 argument and returns an i32
(func (export "exported_func") (param $input i32) (result i32)
;; Invoke `imported_func` with $input as argument
local.get $input
call $i
;; Return $input
local.get $input
return
)
)Использование wat2wasm ↗, преобразуйте формат WAT в WebAssembly Binary Format:
wat2wasm src/simple.wat -o src/simple.wasmBundling
Wrangler упакует любой модуль Wasm, имя которого оканчивается на .wasm или .wasm?module, чтобы он был доступен во время выполнения внутри вашего Worker. Это выполняется с помощью правила сборки по умолчанию, которое можно настроить в конфигурационный файл Wrangler. См. Сборка в Wrangler, где это описано подробнее.
Используйте из JavaScript
После преобразования формата WAT в WebAssembly Binary Format импортируйте и используйте модуль Wasm в существующем Worker на JavaScript или TypeScript:
import mod from "./simple.wasm";
// Define imports available to Wasm instance.
const importObject = {
imports: {
imported_func: (arg: number) => {
console.log(`Hello from JavaScript: ${arg}`);
},
},
};
// Create instance of WebAssembly Module `mod`, supplying
// the expected imports in `importObject`. This should be
// done at the top level of the script to avoid instantiation on every request.
const instance = await WebAssembly.instantiate(mod, importObject);
export default {
async fetch() {
// Invoke the `exported_func` from our Wasm Instance with
// an argument.
const retval = instance.exports.exported_func(42);
// Return the return value!
return new Response(`Success: ${retval}`);
},
};При вызове этот Worker должен логировать Hello from JavaScript: 42 и вернуть Success: 42, демонстрируя возможность вызывать методы Wasm с аргументами из JavaScript и наоборот.
Следующие шаги
На практике вы, скорее всего, будете компилировать выбранный язык (например, Rust) в бинарные файлы WebAssembly. Многие языки предоставляют bindgen чтобы упростить взаимодействие между JavaScript и Wasm. Эти инструменты могут интегрироваться с вашим сборщиком JavaScript и предоставлять API, отличный от WebAssembly API, для инициализации и вызова вашего модуля Wasm. В качестве примера см. Rust wasm-bindgen документация ↗.
Если вы хотите написать весь Worker на Rust, Workers предоставляет многие из тех же Runtime API и привязки при использовании workers-rs крейт. Подробнее см. в Руководство по Workers для Rust.