Volver al inicio

Rust WASM: Portar CLI a Navegador

El artículo describe el portado de una aplicación de consola en Rust a WebAssembly con la creación de una interfaz web al estilo terminal. Desglose de exportación de funciones, compilación wasm-pack, integración JS y despliegue automatizado vía GitLab Pages. El enfoque se adapta a utilidades ligeras sin dependencias del sistema.

Cómo Compilar Rust CLI en WASM y Ejecutarlo en el Navegador
Advertisement 728x90

Migrando una herramienta CLI de Rust a WebAssembly con despliegue en GitLab Pages

Una aplicación de consola para generar predicciones de texto ha sido adaptada a WebAssembly usando Rust. La lógica computacional se aísla en un módulo WASM, mientras que la interfaz se implementa como una página HTML estática con una experiencia de usuario similar a una terminal. El despliegue mediante GitLab Pages proporciona acceso instantáneo a la demo sin necesidad de instalación.

El proyecto incluye una biblioteca Rust para la lógica principal, un frontend construido con JavaScript y CSS vanilla, y artefactos de wasm-pack. Este enfoque es ideal para utilidades ligeras que no requieren acceso al sistema de archivos ni APIs específicas de plataforma.

Arquitectura del proyecto

La estructura se divide en tres componentes:

Google AdInline article slot
  • src/lib.rs — Lógica principal en Rust con funciones exportadas.
  • public/index.html, styles.css, app.js — Interfaz estilo terminal.
  • public/pkg/ — Archivos WASM compilados y envoltorios JavaScript.

La falta de dependencias del sistema operativo hace que la adaptación sea directa: la aplicación acepta comandos y devuelve texto.

Exportando Rust a WASM

La función principal se exporta usando #[wasm_bindgen]:

#[wasm_bindgen]
pub fn generate_reading_text() -> String {
    // Generar y formatear el resultado
}

Compila con el comando:

Google AdInline article slot
wasm-pack build --target no-modules --release --out-dir public/pkg

Resultado: iching_wasm.js y iching_wasm_bg.wasm. La opción --target no-modules simplifica la integración sin bundlers.

Integrando WASM en el navegador

En app.js, el módulo se carga sincrónicamente con WASM embebido en base64 para funcionar con file://:

const wasmBytes = base64ToBytes(window.ICHING_WASM_BASE64);
wasm_bindgen.initSync({ module: wasmBytes });

const text = wasm_bindgen.generate_reading_text();
output.textContent = text;

En index.html, se incluyen:

Google AdInline article slot
  • ./pkg/iching_wasm.js — Runtime.
  • ./pkg/iching_wasm_bg_base64.js — WASM en base64.
  • app.js — Lógica de la interfaz.

JavaScript llama a WASM, y el resultado se renderiza en el DOM.

Interfaz estilo terminal

Interfaz sin frameworks:

  • Contenedor con borde y título de ventana.
  • Fuente monoespaciada (ej., JetBrains Mono).
  • Tema oscuro con texto verde.
  • <pre> para la salida.
  • Entrada para comandos como ./generate_reading.

Imita visual y comportamentalmente una consola. Un botón activa la llamada WASM.

CI/CD para compilación y despliegue

.gitlab-ci.yml automatiza el proceso:

image: rust:slim

create-pages:
  pages:
    publish: public
  rules:
    - if: '$CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH'
  before_script:
    - rustup target add wasm32-unknown-unknown
    - cargo install wasm-pack --locked
  script:
    - wasm-pack build --target no-modules --release --out-dir public/pkg
    - b64="$(base64 public/pkg/iching_wasm_bg.wasm | tr -d '\n')"
    - printf 'window.ICHING_WASM_BASE64 = "%s";\n' "$b64" > public/pkg/iching_wasm_bg_base64.js

Pasos: instalar target, compilar con wasm-pack, codificar WASM a base64, publicar public/ en Pages.

Ventajas de este enfoque

  • Accesibilidad: La demo funciona en cualquier navegador sin Rust o instalación local.
  • Seguridad: El aislamiento de WASM elimina riesgos del código nativo.
  • Simplicidad: Alojamiento estático, un solo trabajo de CI.
  • Portabilidad: Adecuado para herramientas CLI sin llamadas al sistema.

Conclusiones clave

  • La lógica sin dependencias del sistema de archivos o APIs encaja perfectamente en WASM—compila en segundos.
  • La incrustación base64 de WASM resuelve problemas de CORS y file://.
  • GitLab Pages + wasm-pack CI proporciona una tubería lista para prototipos.
  • JavaScript/HTML vanilla para la interfaz minimiza la sobrecarga.
  • #[wasm_bindgen] es el estándar para exportar Rust a JavaScript.

— Editorial Team

Advertisement 728x90

Leer después