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:
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:
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:
./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
Aún no hay comentarios.