wasm-bindgen
Faça a ponte entre Rust e JavaScript com macros wasm-bindgen e geração de código de cola.
Receita
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
format!("Hello, {name}!")
}wasm-pack build --target webQuando usar isso: WASM para navegador que precisa chamar APIs JS e expor funções Rust para JavaScript.
Exemplo de Trabalho
use wasm_bindgen::prelude::*;
use serde::{Deserialize, Serialize};
#[wasm_bindgen]
pub struct Counter {
value: u32,
}
#[wasm_bindgen]
impl Counter {
#[wasm_bindgen(constructor)]
pub fn new() -> Counter {
Counter { value: 0 }
}
pub fn increment(&mut self) {
self.value += 1;
}
pub fn value(&self) -> u32 {
self.value
}
}
#[wasm_bindgen]
pub fn parse_json(input: &str) -> Result<JsValue, JsValue> {
let data: serde_json::Value = serde_json::from_str(input)
.map_err(|e| JsValue::from_str(&e.to_string()))?;
Ok(JsValue::from_serde(&data)?)
}import init, { Counter, parse_json } from "./pkg/mylib.js";
await init();
const c = new Counter();
c.increment();
console.log(c.value());
console.log(parse_json('{"ok":true}'));O que isso demonstra:
#[wasm_bindgen]exporta tipos Rust para classes JSconstructormapeia paranew Counter()JsValueatravessa a fronteira para JSON dinâmicowasm-packgera wrappers JS amigáveis ao TypeScript
Mergulho Profundo
Mapeamento de Tipos
| Rust | JavaScript |
|---|---|
&str / String | string |
u32 / i32 | number |
bool | boolean |
Vec<u8> | Uint8Array |
#[wasm_bindgen] struct | class |
Importando JS
#[wasm_bindgen]
extern "C" {
fn alert(s: &str);
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}Armadilhas
- Propriedade através da fronteira - O JS pode reter referências de forma imprevisível. Correção: Prefira retornos de propriedade (
String,Vec) em vez de empréstimos de longa duração. - Panic em fn exportada - Trava a instância WASM. Correção: Retorne
Result<JsValue, JsValue>para JS. - Tipos não-Send em async -
wasm-bindgen-futuresrequer futuresSend. Correção: Usespawn_localpara futures DOM. - serde e JsValue -
from_serdeprecisa deserde-wasm-bindgenem pilhas modernas. Correção: Useserde-wasm-bindgenpara desempenho. - Tamanho Debug vs release - WASM de depuração é enorme. Correção: Sempre use
--releasepara implantações no navegador.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
Exportações extern "C" brutas | Módulos mínimos sem cola JS | Interop JS rica |
wasm-bindgen-rayon | Computação paralela em navegadores com threads | Aplicativos DOM single-threaded |
| Compilar para WASI em vez disso | WASM do lado do servidor | Acesso DOM do navegador necessário |
FAQs
wasm-bindgen vs wit-bindgen?
wasm-bindgen tem como alvo navegadores e JS. WIT/Component Model usa wit-bindgen para interfaces portáteis.
Como passo structs para JS?
Marque structs com #[wasm_bindgen] e exponha métodos em blocos impl.
Rust Assíncrono em WASM?
Use wasm-bindgen-futures e a ponte js_sys::Promise.
Posso usar std em WASM?
Sim para a maioria dos módulos. wasm32-unknown-unknown não tem sistema operacional, mas std funciona na maioria das vezes com shims.
Testando sem um navegador?
Use wasm-bindgen-test em navegadores headless ou wasmtime para lógica não-DOM.
Mapas de origem?
Habilite símbolos de depuração no perfil de desenvolvimento. wasm-pack build --dev inclui nomes para rastreamentos de pilha.
Múltiplos crates?
Membros de workspace podem ser crates WASM. Vincule com rlib e uma entrada cdylib.
Callbacks de closure?
Closure::wrap passa callbacks Rust para manipuladores de eventos JS. Lembre-se de forget ou armazenar para manter vivo.
Suporte a BigInt?
Use js_sys::BigInt para inteiros de 64 bits além do intervalo seguro de Number do JS.
Layout do pacote npm?
wasm-pack build --target bundler para webpack/vite. --target web para módulos ES diretos do navegador.
Relacionado
- Noções Básicas de WebAssembly - alvos e compilações
- wasm-pack & Bundling - enviando pacotes npm
- DOM & Web APIs (web-sys) - APIs do navegador
- Desempenho & Tamanho - encolhendo binários
Versões da Pilha: Esta página foi escrita para Rust 1.97.0 (edição 2024), Tokio 1.x, Axum 0.8, serde 1.0, sqlx 0.8, clap 4, e Polars 0.46+.