Rust y WebAssembly
Sin nada
Añadir wasm al compilador:
1rustup component add wasm32-unknown-unknown
Cargo.toml
lib.rs
Compilar:
1cargo build --target wasm32-unknow-unknown
Script que cargará y ejecutará la función:
1async function load_wasm(path) { 2 const {instance} = await WebAssembly.getinstantiateStreaming(fetch(path)); 3 4 if (instance) { 5 return instance; 6 } else { 7 throw `Error loading ${path}: instance is undefined`; 8 } 9} 10 11function main() { 12 const wasm = load_wasm("./target/wasm32-unknown-unknown/debug/<nombre>.wasm") 13 console.log(wasm.double(2)); // Se imprimirá 2 14}
La página web se tendrá que mostrar en un servidor por temas de seguridad:
1python -m http.server
Con WASM-PACK y WASM-BINDGEN
Descargué wasm_pack, porque
cargo install wasm-pack
daba error de compilación.Escribí un archivo por lotes que crea un servidor en python y abre la página en Chrome, porque por temas de seguridad, los navegadores no permiten acceso a archivos (como el .wasm).
Cargo.toml
y.gitignore
1[package] 2name = "<nombre>" 3# ... 4 5# Con esto, no se pueden llamar funciones de `lib.rs` desde un 6# binario como `main.rs` 7[lib] 8crate-type = ["cdylib"] 9 10[dependencies] 11wasm-bindgen = "*" 12 13# Opcional, pero es buena idea hacer que `release` se 14# centre en hacerlo pequeño para enviarlo por internet 15[profile.release] 16opt-level = "s"
Para llamar funciones de JavaScript desde Rust se usa:
1use wasm_bindgen::prelude::*; 2 3#[wasm-bingen] 4extern { 5 // La función. Ejemplo: 6 fn alert(msg: &str); 7} 8 9// Esta función se puede llamar desde JavaScript 10#[wasm-bingen] 11fn greet(name: &str) { 12 // Se queja porque el `unsafe` es innecesario 13 // Pero si lo quito lo marca como error y no corrige otros errores 14 // Sin embargo, no produce ningún error al compilar 15 alert(&format("Hello {}", name)); 16}
El HTML básico (el nombre no acaba en
bg
):1<!DOCTYPE html> 2<html> 3<body> 4 <!-- `type="module"` es para no tener que escribir un `.js` por 5 separado, ya que `import` solo funciona en un módulo --> 6 <script type="module"> 7 import init, {<nombre_función>} from "./pkg/<nombre>.js"; 8 9 init() 10 .then(() => { 11 // ... 12 }); 13 </script> 14</body> 15</html>
Exceptuando el archivo
.wasm
y<nombre>.js
, son todos innecesarios.