Node.js con WebAssembly
WebAssembly es un lenguaje de tipo ensamblador de alto rendimiento que se puede compilar desde varios lenguajes, incluidos C/C++, Rust y AssemblyScript. ¡Actualmente, es compatible con Chrome, Firefox, Safari, Edge y Node.js!
La especificación de WebAssembly detalla dos formatos de archivo, un formato binario llamado Módulo WebAssembly con una extensión .wasm
y la representación de texto correspondiente llamada formato de texto WebAssembly con una extensión .wat
.
Conceptos clave
- Módulo: un binario WebAssembly compilado, es decir, un archivo
.wasm
. - Memoria: un ArrayBuffer redimensionable.
- Tabla: una matriz tipada redimensionable de referencias no almacenadas en la memoria.
- Instancia: una instancia de un módulo con su memoria, tabla y variables.
Para usar WebAssembly, necesita un archivo binario .wasm
y un conjunto de API para comunicarse con WebAssembly. Node.js proporciona las API necesarias a través del objeto global WebAssembly
.
console.log(WebAssembly)
/*
Object [WebAssembly] {
compile: [Function: compile],
validate: [Function: validate],
instantiate: [Function: instantiate]
}
*/
Generando módulos WebAssembly
Existen varios métodos disponibles para generar archivos binarios WebAssembly, que incluyen:
- Escribir WebAssembly (
.wat
) a mano y convertirlo a formato binario utilizando herramientas como wabt. - Usar emscripten con una aplicación C/C++
- Usar wasm-pack con una aplicación Rust
- Usar AssemblyScript si prefiere una experiencia similar a TypeScript
TIP
Algunas de estas herramientas generan no solo el archivo binario, sino también el código JavaScript "glue" y los archivos HTML correspondientes para ejecutarse en el navegador.
Cómo usarlo
Una vez que tenga un módulo WebAssembly, puede usar el objeto WebAssembly
de Node.js para instanciarlo.
const fs = require('node:fs')
const wasmBuffer = fs.readFileSync('/path/to/add.wasm')
WebAssembly.instantiate(wasmBuffer).then(wasmModule => {
// La función exportada vive en instance.exports
const { add } = wasmModule.instance.exports
const sum = add(5, 6)
console.log(sum) // Imprime: 11
})
Interacción con el SO
Los módulos de WebAssembly no pueden acceder directamente a la funcionalidad del SO por sí mismos. Se puede utilizar una herramienta de terceros, Wasmtime, para acceder a esta funcionalidad. Wasmtime
utiliza la API WASI para acceder a la funcionalidad del SO.