Introdução ao WebAssembly com Rust
WebAssembly (WASM) é um formato binário que permite executar código de alto desempenho no navegador, complementando JavaScript. Rust é a linguagem ideal para compilar para WASM devido à sua segurança, ausência de garbage collector e controle fino de memória. O wasm-pack é a ferramenta oficial que simplifica todo o fluxo: compila código Rust para WebAssembly, gera bindings JavaScript automaticamente e prepara o código para publicação em npm. Este artigo o guiará desde a instalação até a criação de projetos prontos para produção.
Configuração Inicial e Instalação
Pré-requisitos e Setup
Você precisará do Rust instalado (via rustup.rs) e do wasm-pack. Instale ambos com:
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
cargo install wasm-pack
Após instalação, configure Rust para compilar para WebAssembly:
rustup target add wasm32-unknown-unknown
Criando o Projeto
Crie um novo projeto WASM:
cargo new --lib meu_projeto_wasm
cd meu_projeto_wasm
Modifique o arquivo Cargo.toml para incluir as dependências corretas:
[package]
name = "meu_projeto_wasm"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib", "rlib"]
[dependencies]
wasm-bindgen = "0.2"
web-sys = "0.3"
[dev-dependencies]
wasm-bindgen-test = "1"
A diretiva cdylib instrui Rust a compilar como uma biblioteca dinâmica (necessária para WASM). As dependências wasm-bindgen e web-sys permitem interação entre Rust e JavaScript.
Desenvolvendo Sua Primeira Aplicação WASM
Exemplo Prático: Calculadora de Fibonacci
Abra src/lib.rs e implemente uma função WASM:
use wasm_bindgen::prelude::*;
#[wasm_bindgen]
pub fn fibonacci(n: u32) -> u32 {
match n {
0 => 0,
1 => 1,
_ => fibonacci(n - 1) + fibonacci(n - 2),
}
}
#[wasm_bindgen]
pub fn greet(name: &str) -> String {
format!("Olá, {}! Bem-vindo ao WebAssembly.", name)
}
O atributo #[wasm_bindgen] expõe funções Rust para JavaScript automaticamente. Compile com:
wasm-pack build --target web
Isso gera uma pasta pkg/ contendo: o arquivo .wasm compilado, um arquivo JavaScript com bindings, e um package.json. O --target web cria código para navegadores modernos.
Integrando com HTML e JavaScript
Crie um arquivo index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>WASM com Rust</title>
</head>
<body>
<h1>Calculadora Fibonacci</h1>
<input type="number" id="numero" placeholder="Digite um número" />
<button onclick="calcular()">Calcular</button>
<p id="resultado"></p>
<script type="module">
import init, { fibonacci, greet } from './pkg/meu_projeto_wasm.js';
async function setup() {
await init();
console.log(greet("Desenvolvedor"));
}
window.calcular = function() {
const { fibonacci } = window.wasmFuncs;
const n = parseInt(document.getElementById('numero').value);
const resultado = fibonacci(n);
document.getElementById('resultado').textContent = `F(${n}) = ${resultado}`;
};
setup().then(() => {
window.wasmFuncs = { fibonacci, greet };
});
</script>
</body>
</html>
Execute um servidor local (python -m http.server 8000) e abra http://localhost:8000 para testar.
Operações Avançadas com Web APIs
Manipulando o DOM com web-sys
Quando precisa interagir diretamente com o DOM, use web-sys. Exemplo de aplicação que modifica elementos HTML:
use wasm_bindgen::prelude::*;
use web_sys::window;
#[wasm_bindgen]
pub fn atualizar_titulo(novo_titulo: &str) {
let document = window()
.expect("sem window")
.document()
.expect("sem document");
if let Some(element) = document.get_element_by_id("titulo") {
element.set_inner_html(novo_titulo);
}
}
#[wasm_bindgen]
pub fn processar_array(valores: &[u32]) -> u32 {
valores.iter().sum()
}
Chame estas funções do JavaScript normalmente: processar_array([10, 20, 30]) retorna 60.
Otimização e Debugging
Use wasm-pack build --release para produção (otimizações agressivas). Para debugging, compile com --dev e use console_error_panic_hook:
#[wasm_bindgen]
pub fn init_panic_hook() {
#[cfg(feature = "console_error_panic_hook")]
console_error_panic_hook::set_once();
}
Adicione no Cargo.toml:
[features]
default = ["console_error_panic_hook"]
[dependencies.console_error_panic_hook]
version = "0.1"
optional = true
Publicação e Distribuição
O wasm-pack gera um package.json pronto para npm. Para publicar, registre uma conta em npmjs.com e execute:
cd pkg
npm publish
Desenvolvedores podem então instalar sua biblioteca:
npm install meu_projeto_wasm
E usá-la em qualquer projeto JavaScript moderno. Sempre versionize incrementalmente e mantenha um CHANGELOG detalhado.
Conclusão
Você aprendeu que: (1) WebAssembly com Rust via wasm-pack oferece compilação segura e automática para navegadores, eliminando manualmente escrever bindings; (2) a integração com JavaScript é transparente — funções Rust marcadas com #[wasm_bindgen] funcionam nativamente no browser; (3) o fluxo completo, do desenvolvimento ao npm, é simplificado pela toolchain oficial, permitindo focar em lógica de negócio.
WebAssembly não substitui JavaScript, mas potencializa aplicações computacionalmente intensivas. Comece com funções críticas em performance e expanda conforme necessário.