Noções Básicas de WebAssembly
10 exemplos introduzindo WebAssembly e os alvos de compilação wasm32 do Rust.
Pré-requisitos
- Rust 1.97.0 com o alvo
wasm32-unknown-unknowninstalado - Familiaridade básica com Cargo e módulos
rustup target add wasm32-unknown-unknownExemplos Básicos
1. Módulo WASM "Olá"
// src/lib.rs
#[no_mangle]
pub extern "C" fn add(a: i32, b: i32) -> i32 {
a + b
}cargo build --target wasm32-unknown-unknown --release- WASM exporta funções para hosts JavaScript
#[no_mangle]mantém os nomes dos símbolos estáveis- A saída é um binário
.wasmemtarget/wasm32-unknown-unknown/release/ - Sem função
mainem módulos do tipo biblioteca
2. wasm32 vs wasm32-wasi
| Alvo | Ambiente Host |
|---|---|
wasm32-unknown-unknown | Navegadores via wasm-bindgen |
wasm32-wasi | Runtimes WASI (Wasmtime, Node) |
Escolha o alvo que corresponde ao seu ambiente de implantação.
3. Perfil de Release para Tamanho
[profile.release]
opt-level = "s"
lto = true
strip = true
codegen-units = 1opt-level = "s"otimiza para tamanho em vez de velocidade- LTO remove código morto entre crates
- O tamanho do download do WASM é importante em navegadores
- Combine com
wasm-optpara encolhimento adicional
4. WASM #![no_std]
#![no_std]
#[panic_handler]
fn panic(_: &core::panic::PanicInfo) -> ! {
loop {}
}
#[no_mangle]
pub extern "C" fn double(x: i32) -> i32 {
x * 2
}- WASM estilo embarcado sem alocador
- Necessário para os módulos menores
- Sem
StringouVecsem um crate de alocador - Comum em motores de jogos e plugins
5. Logging de WASM
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(s: &str);
}
pub fn info(msg: &str) {
log(msg);
}- Importa funções JavaScript para Rust
console.logé o caminho de depuração mais simples- Prefira
web_sys::consoleem projetos reais - Remova imports de depuração em builds de produção
Relacionado: wasm-bindgen
6. Gancho de Pânico para Navegadores
use console_error_panic_hook;
use wasm_bindgen::prelude::*;
#[wasm_bindgen(start)]
pub fn init() {
console_error_panic_hook::set_once();
}- Pânicos do Rust se tornam erros legíveis no console do navegador
- Chame uma vez na inicialização do módulo
- Essencial para desenvolvimento; opcional em produção
- Funciona com
#[wasm_bindgen(start)]
7. Cargo.toml para Crates WASM
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
wasm-bindgen = "0.2"cdylibproduz o artefato.wasmrlibpermite testes de integração Rust no alvo nativo- Mantenha as dependências compatíveis com WASM (sem crates de SO nativos)
Exemplos Intermediários
8. Inspecionar Saída WASM
wasm-objdump -x target/wasm32-unknown-unknown/release/mylib.wasm
wasm2wat target/wasm32-unknown-unknown/release/mylib.wasm | headwasm-objdumpmostra exports, imports e tamanhoswasm2watdesmonta para formato de texto para depuração- Instale via
wasm-toolsou WABT - Verifique se os nomes de exportação correspondem às expectativas da cola JS
9. Carregador HTML Mínimo
<script type="module">
const { default: init, add } = await import("./pkg/mylib.js");
await init();
console.log(add(2, 3));
</script>- Navegadores modernos carregam WASM como módulos ES
wasm-packgera a cola JSinit()carrega o arquivo.wasmde forma assíncrona- Sirva com o
Content-Type: application/wasmcorreto
Relacionado: wasm-pack e Bundling
10. Quando Não Usar WASM
- Manipulação pesada do DOM (JavaScript pode ser mais simples)
- Acesso direto ao sistema de arquivos em navegadores (use APIs ou WASI)
- Scripts minúsculos onde o bundle JS já está carregado
Rust WASM brilha para trabalho computacionalmente intensivo: parsers, codecs, criptografia e simulações.
Versões da Stack: 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+.