Rust y WebAssembly
Sin nada
Añadir wasm al compilador:
rustup component add wasm32-unknown-unknownCargo.toml
# ... # Con esto, no se pueden llamar funciones de `lib.rs` desde un # binario como `main.rs` [lib] crate-type = ["cdylib"]lib.rs
// No cambia el nombre de la función para unirla más fácil #[no_mangle] pub fn double(number: i32) -> i32 { 2 * number }Compilar:
cargo build --target wasm32-unknow-unknownScript que cargará y ejecutará la función:
async function load_wasm(path) { const {instance} = await WebAssembly.getinstantiateStreaming(fetch(path)); if (instance) { return instance; } else { throw `Error loading ${path}: instance is undefined`; } } function main() { const wasm = load_wasm("./target/wasm32-unknown-unknown/debug/<nombre>.wasm") console.log(wasm.double(2)); // Se imprimirá 2 }La página web se tendrá que mostrar en un servidor por temas de seguridad:
python -m http.server
Con WASM-PACK y WASM-BINDGEN
Descargué wasm_pack, porque
cargo install wasm-packdaba 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).
@echo off wasm-pack build --target web REM Abre la pagina primero porque el servidor detendrá el programa start chrome http://localhost:8000 python -m http.serverCargo.tomly.gitignore[package] name = "<nombre>" # ... # Con esto, no se pueden llamar funciones de `lib.rs` desde un # binario como `main.rs` [lib] crate-type = ["cdylib"] [dependencies] wasm-bindgen = "*" # Opcional, pero es buena idea hacer que `release` se # centre en hacerlo pequeño para enviarlo por internet [profile.release] opt-level = "s"/target /pkgPara llamar funciones de JavaScript desde Rust se usa:
use wasm_bindgen::prelude::*; #[wasm-bingen] extern { // La función. Ejemplo: fn alert(msg: &str); } // Esta función se puede llamar desde JavaScript #[wasm-bingen] fn greet(name: &str) { // Se queja porque el `unsafe` es innecesario // Pero si lo quito lo marca como error y no corrige otros errores // Sin embargo, no produce ningún error al compilar alert(&format("Hello {}", name)); }El HTML básico (el nombre no acaba en
bg):<!DOCTYPE html> <html> <body> <!-- `type="module"` es para no tener que escribir un `.js` por separado, ya que `import` solo funciona en un módulo --> <script type="module"> import init, {<nombre_función>} from "./pkg/<nombre>.js"; init() .then(() => { // ... }); </script> </body> </html>Exceptuando el archivo
.wasmy<nombre>.js, son todos innecesarios.