Trabajo con WebAssembly y JavaScript: de la A a la Z en Node.js

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Introducción a WebAssembly y su papel en Node.js

\n\n

WebAssembly (WASM) es un formato de instrucciones binarias de bajo nivel que se ejecuta en una máquina virtual con un rendimiento casi nativo. En el ecosistema de Node.js, WebAssembly abre nuevos horizontes: permite ejecutar código escrito en C, C++, Rust o Go directamente en el entorno del servidor. Esto es especialmente relevante para tareas que requieren alto rendimiento: procesamiento de imágenes, criptografía, análisis de datos, trabajo con grandes arreglos de números.

\n\n

En este artículo, analizaremos el ciclo completo de trabajo con WebAssembly en Node.js: desde la compilación del código fuente hasta la integración del módulo terminado en una aplicación JavaScript.

\n\n

Conceptos básicos y preparación del entorno

\n\n

Qué necesita saber antes de comenzar

\n

Un módulo WebAssembly es un archivo binario con la extensión .wasm. No tiene acceso directo al DOM ni al sistema de archivos: toda la interacción se realiza a través de "funciones importadas" que usted pasa desde JavaScript. En Node.js, esta limitación se elimina mediante envoltorios especiales.

\n\n

Instalación de herramientas

\n

Para compilar código a WASM necesitamos el SDK de Emscripten. Instalación en Linux/macOS:

\n
git clone https://github.com/emscripten-core/emsdk.git\ncd emsdk\n./emsdk install latest\n./emsdk activate latest\nsource ./emsdk_env.sh
\n\n

Para proyectos Rust, use wasm-pack:

\n
npm install -g wasm-pack
\n\n

Creación y compilación del primer módulo WASM

\n\n

Ejemplo en C: función de suma

\n

Creemos una función simple en C que suma dos números:

\n
// math.c\n#include <emscripten.h>\n\nEMSCRIPTEN_KEEPALIVE\nint add(int a, int b) {\n    return a + b;\n}\n\nEMSCRIPTEN_KEEPALIVE\nint multiply(int a, int b) {\n    return a * b;\n}
\n\n

Compilamos a WASM con Emscripten:

\n
emcc math.c -o math.js -s EXPORTED_FUNCTIONS="['_add', '_multiply']" -s WASM=1 -s MODULARIZE=1 -s EXPORT_NAME="createMathModule"
\n\n

Como resultado, obtenemos dos archivos: math.wasm y math.js, un envoltorio para la carga.

\n\n

Carga del módulo en Node.js

\n

Ahora usamos el módulo en JavaScript:

\n
// index.js\nconst createMathModule = require('./math.js');\n\ncreateMathModule().then(module => {\n    const add = module._add;\n    const multiply = module._multiply;\n\n    console.log('5 + 3 =', add(5, 3));        // 8\n    console.log('4 * 7 =', multiply(4, 7));  // 28\n});
\n\n

Ejecutamos:

\n
node index.js
\n\n

Trabajo con memoria y tipos de datos complejos

\n\n

Paso de cadenas y arreglos

\n

WASM solo opera con números. Para pasar cadenas o arreglos, es necesario asignar memoria en la memoria lineal del módulo. Veamos un ejemplo en C que recibe una cadena y devuelve su longitud:

\n
// string_ops.c\n#include <string.h>\n#include <emscripten.h>\n\nEMSCRIPTEN_KEEPALIVE\nint string_length(char* str) {\n    return strlen(str);\n}\n\nEMSCRIPTEN_KEEPALIVE\nvoid to_upper(char* str) {\n    for (int i = 0; str[i]; i++) {\n        if (str[i] >= 'a' && str[i] <= 'z') {\n            str[i] -= 32;\n        }\n    }\n}
\n\n

Compilamos:

\n
emcc string_ops.c -o string_ops.js -s EXPORTED_FUNCTIONS="['_string_length', '_to_upper']" -s WASM=1 -s MODULARIZE=1 -s EXPORT_NAME="createStringModule"
\n\n

Código JavaScript para trabajar con memoria:

\n
const createStringModule = require('./string_ops.js');\n\ncreateStringModule().then(module => {\n    const { _string_length, _to_upper, heap } = module;\n    \n    // Asignamos memoria para la cadena\n    const input = "hello world";\n    const ptr = module._malloc(input.length + 1);\n    \n    // Copiamos la cadena a la memoria WASM\n    for (let i = 0; i < input.length; i++) {\n        heap[i + ptr] = input.charCodeAt(i);\n    }\n    heap[ptr + input.len                

Blogs

Book Recommendations