Rust

O que Todo Dev Deve Saber sobre WebAssembly com Rust: Compilando para o Navegador com wasm-pack

8 min de leitura

O que Todo Dev Deve Saber sobre WebAssembly com Rust: Compilando para o Navegador com wasm-pack

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 é 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 ) e do . Instale ambos com: Após instalação, configure Rust para compilar para WebAssembly: Criando o Projeto Crie um novo projeto WASM: Modifique o arquivo para incluir as dependências corretas: A diretiva instrui Rust a compilar como uma biblioteca dinâmica (necessária para WASM). As dependências e permitem interação entre Rust e JavaScript. Desenvolvendo Sua Primeira Aplicação WASM Exemplo Prático: Calculadora

<h2>Introdução ao WebAssembly com Rust</h2>

<p>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 <code>wasm-pack</code> é 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.</p>

<h2>Configuração Inicial e Instalação</h2>

<h3>Pré-requisitos e Setup</h3>

<p>Você precisará do Rust instalado (via <code>rustup.rs</code>) e do <code>wasm-pack</code>. Instale ambos com:</p>

<pre><code class="language-bash">curl --proto &#039;=https&#039; --tlsv1.2 -sSf https://sh.rustup.rs | sh

cargo install wasm-pack</code></pre>

<p>Após instalação, configure Rust para compilar para WebAssembly:</p>

<pre><code class="language-bash">rustup target add wasm32-unknown-unknown</code></pre>

<h3>Criando o Projeto</h3>

<p>Crie um novo projeto WASM:</p>

<pre><code class="language-bash">cargo new --lib meu_projeto_wasm

cd meu_projeto_wasm</code></pre>

<p>Modifique o arquivo <code>Cargo.toml</code> para incluir as dependências corretas:</p>

<pre><code class="language-toml">[package]

name = &quot;meu_projeto_wasm&quot;

version = &quot;0.1.0&quot;

edition = &quot;2021&quot;

[lib]

crate-type = [&quot;cdylib&quot;, &quot;rlib&quot;]

[dependencies]

wasm-bindgen = &quot;0.2&quot;

web-sys = &quot;0.3&quot;

[dev-dependencies]

wasm-bindgen-test = &quot;1&quot;</code></pre>

<p>A diretiva <code>cdylib</code> instrui Rust a compilar como uma biblioteca dinâmica (necessária para WASM). As dependências <code>wasm-bindgen</code> e <code>web-sys</code> permitem interação entre Rust e JavaScript.</p>

<h2>Desenvolvendo Sua Primeira Aplicação WASM</h2>

<h3>Exemplo Prático: Calculadora de Fibonacci</h3>

<p>Abra <code>src/lib.rs</code> e implemente uma função WASM:</p>

<pre><code class="language-rust">use wasm_bindgen::prelude::*;

#[wasm_bindgen]

pub fn fibonacci(n: u32) -&gt; u32 {

match n {

0 =&gt; 0,

1 =&gt; 1,

_ =&gt; fibonacci(n - 1) + fibonacci(n - 2),

}

}

#[wasm_bindgen]

pub fn greet(name: &amp;str) -&gt; String {

format!(&quot;Olá, {}! Bem-vindo ao WebAssembly.&quot;, name)

}</code></pre>

<p>O atributo <code>#[wasm_bindgen]</code> expõe funções Rust para JavaScript automaticamente. Compile com:</p>

<pre><code class="language-bash">wasm-pack build --target web</code></pre>

<p>Isso gera uma pasta <code>pkg/</code> contendo: o arquivo <code>.wasm</code> compilado, um arquivo JavaScript com bindings, e um <code>package.json</code>. O <code>--target web</code> cria código para navegadores modernos.</p>

<h3>Integrando com HTML e JavaScript</h3>

<p>Crie um arquivo <code>index.html</code>:</p>

<pre><code class="language-html">&lt;!DOCTYPE html&gt;

&lt;html&gt;

&lt;head&gt;

&lt;meta charset=&quot;UTF-8&quot;&gt;

&lt;title&gt;WASM com Rust&lt;/title&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;h1&gt;Calculadora Fibonacci&lt;/h1&gt;

&lt;input type=&quot;number&quot; id=&quot;numero&quot; placeholder=&quot;Digite um número&quot; /&gt;

&lt;button onclick=&quot;calcular()&quot;&gt;Calcular&lt;/button&gt;

&lt;p id=&quot;resultado&quot;&gt;&lt;/p&gt;

&lt;script type=&quot;module&quot;&gt;

import init, { fibonacci, greet } from &#039;./pkg/meu_projeto_wasm.js&#039;;

async function setup() {

await init();

console.log(greet(&quot;Desenvolvedor&quot;));

}

window.calcular = function() {

const { fibonacci } = window.wasmFuncs;

const n = parseInt(document.getElementById(&#039;numero&#039;).value);

const resultado = fibonacci(n);

document.getElementById(&#039;resultado&#039;).textContent = F(${n}) = ${resultado};

};

setup().then(() =&gt; {

window.wasmFuncs = { fibonacci, greet };

});

&lt;/script&gt;

&lt;/body&gt;

&lt;/html&gt;</code></pre>

<p>Execute um servidor local (<code>python -m http.server 8000</code>) e abra <code>http://localhost:8000</code> para testar.</p>

<h2>Operações Avançadas com Web APIs</h2>

<h3>Manipulando o DOM com web-sys</h3>

<p>Quando precisa interagir diretamente com o DOM, use <code>web-sys</code>. Exemplo de aplicação que modifica elementos HTML:</p>

<pre><code class="language-rust">use wasm_bindgen::prelude::*;

use web_sys::window;

#[wasm_bindgen]

pub fn atualizar_titulo(novo_titulo: &amp;str) {

let document = window()

.expect(&quot;sem window&quot;)

.document()

.expect(&quot;sem document&quot;);

if let Some(element) = document.get_element_by_id(&quot;titulo&quot;) {

element.set_inner_html(novo_titulo);

}

}

#[wasm_bindgen]

pub fn processar_array(valores: &amp;[u32]) -&gt; u32 {

valores.iter().sum()

}</code></pre>

<p>Chame estas funções do JavaScript normalmente: <code>processar_array([10, 20, 30])</code> retorna 60.</p>

<h3>Otimização e Debugging</h3>

<p>Use <code>wasm-pack build --release</code> para produção (otimizações agressivas). Para debugging, compile com <code>--dev</code> e use <code>console_error_panic_hook</code>:</p>

<pre><code class="language-rust">#[wasm_bindgen]

pub fn init_panic_hook() {

#[cfg(feature = &quot;console_error_panic_hook&quot;)]

console_error_panic_hook::set_once();

}</code></pre>

<p>Adicione no <code>Cargo.toml</code>:</p>

<pre><code class="language-toml">[features]

default = [&quot;console_error_panic_hook&quot;]

[dependencies.console_error_panic_hook]

version = &quot;0.1&quot;

optional = true</code></pre>

<h2>Publicação e Distribuição</h2>

<p>O <code>wasm-pack</code> gera um <code>package.json</code> pronto para npm. Para publicar, registre uma conta em npmjs.com e execute:</p>

<pre><code class="language-bash">cd pkg

npm publish</code></pre>

<p>Desenvolvedores podem então instalar sua biblioteca:</p>

<pre><code class="language-bash">npm install meu_projeto_wasm</code></pre>

<p>E usá-la em qualquer projeto JavaScript moderno. Sempre versionize incrementalmente e mantenha um CHANGELOG detalhado.</p>

<h2>Conclusão</h2>

<p>Você aprendeu que: <strong>(1)</strong> WebAssembly com Rust via <code>wasm-pack</code> oferece compilação segura e automática para navegadores, eliminando manualmente escrever bindings; <strong>(2)</strong> a integração com JavaScript é transparente — funções Rust marcadas com <code>#[wasm_bindgen]</code> funcionam nativamente no browser; <strong>(3)</strong> o fluxo completo, do desenvolvimento ao npm, é simplificado pela toolchain oficial, permitindo focar em lógica de negócio.</p>

<p>WebAssembly não substitui JavaScript, mas potencializa aplicações computacionalmente intensivas. Comece com funções críticas em performance e expanda conforme necessário.</p>

<h2>Referências</h2>

<ul>

<li><a href="https://rustwasm.org/docs/wasm-pack/" target="_blank" rel="noopener noreferrer">Documentação Oficial wasm-pack</a></li>

<li><a href="https://rustwasm.org/docs/book/" target="_blank" rel="noopener noreferrer">The Rust and WebAssembly Book</a></li>

<li><a href="https://developer.mozilla.org/en-US/docs/WebAssembly" target="_blank" rel="noopener noreferrer">MDN: WebAssembly Concepts</a></li>

<li><a href="https://doc.rust-lang.org/cargo/guide/creating-a-new-project.html" target="_blank" rel="noopener noreferrer">Cargo Book: Library Crates</a></li>

<li><a href="https://docs.rs/web-sys/" target="_blank" rel="noopener noreferrer">web-sys Documentation</a></li>

</ul>

Comentários

Mais em Rust

Boas Práticas de String vs &str em Rust: Entendendo as Duas Formas de Texto para Times Ágeis
Boas Práticas de String vs &str em Rust: Entendendo as Duas Formas de Texto para Times Ágeis

String vs &amp;str em Rust: Entendendo as Duas Formas de Texto O que são Stri...

Leitura e Escrita de Arquivos em Rust com std::fs: Do Básico ao Avançado
Leitura e Escrita de Arquivos em Rust com std::fs: Do Básico ao Avançado

Introdução ao Módulo std::fs O módulo (filesystem) é a porta de entrada para...

Boas Práticas de Biblioteca thiserror: Erros Ergonômicos em Rust para Times Ágeis
Boas Práticas de Biblioteca thiserror: Erros Ergonômicos em Rust para Times Ágeis

Entendendo a Biblioteca thiserror A biblioteca é um derive macro que simplifi...