Geekflare cuenta con el apoyo de nuestra audiencia. Podemos ganar comisiones de afiliados comprando enlaces en este sitio.
Comparte en:

WebAssembly para principiantes Parte 4: WebAssembly y JavaScript Companionship

Compañero de WebAssembly y JavaScript
Escáner de seguridad de aplicaciones web Invicti – la única solución que ofrece verificación automática de vulnerabilidades con Proof-Based Scanning™.

En la parte 4 de WebAssembly para principiantes, veremos de cerca la compañía de WebAssembly y JavaScript.

Aquí, aprenderá a usar WebAssembly en su JavaScript. Además, también exploraremos la API JavaScript de WebAssembly.

WebAssemebly es un estándar abierto de formato binario que permite a los desarrolladores ejecutar aplicaciones con un rendimiento nativo en los navegadores. Si no ha leído al respecto, le sugerimos que consulte las partes anteriores de nuestra guía.

Empecemos.

Using WebAssembly With JavaScript

En nuestro tutorial de WebAssembly parte 1, discutimos cómo funciona WASM. Para escribir código de alto rendimiento para su aplicación web, debe usar funciones y API de WASM dentro de JavaScript. También discutimos cómo los marcos de JavaScript podrían usar WASM para crear aplicaciones de alto rendimiento.

Sin embargo, actualmente no puede cargar módulos WASM como módulos ES6 usando el . That’s where JavaScript comes in. It helps in loading and compiling WASM on the browser. The exact steps to do so are as below:

  • Cargue los bytes .wasm en ArrayBuffer o matriz escrita.
  • Use WebAssembly.Module para compilar bytes.
  • Ahora, cree una instancia de WebAssembly.Module con importaciones para obtener exportaciones llamables

Por lo tanto, debe comenzar con el módulo WASM precompilado. Aquí, tienes muchas opciones. Puedes usar Herrumbre, C/C++, AssemblyScript e incluso TinyGo(Go) para escribir su código y luego transformarlo en un módulo .wasm.

Técnicamente, WebAssembly es un objetivo de compilación para idiomas. Esto significa que deberá escribir el código en el idioma que elija y luego usar el código binario generado dentro de la aplicación (web o no web). Además, si tiene la intención de usarlo en servidores, deberá usar WASI para interactuar con los sistemas.

Como WebAssembly usa memoria lineal a través de una matriz expandible, tanto JavaScript como WASM pueden acceder a ella de manera sincrónica, lo que le brinda la capacidad de escribir aplicaciones rápidas y ricas en funciones.

WebAssembly and JavaScript Examples

Usemos ejemplos para aprender cómo puede usar WASM con JavaScript. 

Como se mencionó anteriormente, necesita un módulo WASM precompilado. Para este ejemplo, usaremos Emscripten (C/C++). Como WASM ofrece un formato binario de alto rendimiento, podemos ejecutar el código generado junto con JavaScript u otros lenguajes.

Configuración de herramientas

Como estamos usando Emscripten, necesitamos obtener emsdk herramienta. Le permitirá compilar su código C/C++ en código .wasm.

Simplemente ejecute el siguiente comando en su terminal. Si no tiene GIT instalado, siga nuestro Código abierto 101: Sistema de control de versiones y Git guía para hacerlo.

git clone https://github.com/emscripten-core/emsdk.git
cd emsdk
#Output

nitt@nitt-laptop:~/Projects/WASM2$ git clone https://github.com/emscripten-core/emsdk.git
Cloning into 'emsdk'...
remote: Enumerating objects: 3566, done.
remote: Counting objects: 100% (62/62), done.
remote: Compressing objects: 100% (49/49), done.
remote: Total 3566 (delta 31), reused 38 (delta 13), pack-reused 3504
Receiving objects: 100% (3566/3566), 2.09 MiB | 2.24 MiB/s, done.
Resolving deltas: 100% (2334/2334), done.
nitt@nitt-laptop:~/Projects/WASM2$ cd emsdk
nitt@nitt-laptop:~/Projects/WASM2/emsdk$

En primera emdsk carpeta, llamamos a otro comando para obtener la última compilación de Emscripten lista para usar. 

Para hacerlo, debe ejecutar los siguientes comandos.

./emsdk install latest
./emsdk activate latest
source ./emsdk_env.sh
#Output

nitt@nitt-laptop:~/Projects/WASM2/emsdk$ ./emsdk install latest
Resolving SDK alias 'latest' to '3.1.31'
Resolving SDK version '3.1.31' to 'sdk-releases-1eec24930cb2f56f6d9cd10ffcb031e27ea4157a-64bit'
Installing SDK 'sdk-releases-1eec24930cb2f56f6d9cd10ffcb031e27ea4157a-64bit'..
Installing tool 'node-14.18.2-64bit'..
Downloading: /home/nitt/Projects/WASM2/emsdk/zips/node-v14.18.2-linux-x64.tar.xz from https://storage.googleapis.com/webassembly/emscripten-releases-builds/deps/node-v14.18.2-linux-x64.tar.xz, 21848416 Bytes
Unpacking '/home/nitt/Projects/WASM2/emsdk/zips/node-v14.18.2-linux-x64.tar.xz' to '/home/nitt/Projects/WASM2/emsdk/node/14.18.2_64bit'
Done installing tool 'node-14.18.2-64bit'.
Installing tool 'releases-1eec24930cb2f56f6d9cd10ffcb031e27ea4157a-64bit'..
Downloading: /home/nitt/Projects/WASM2/emsdk/zips/1eec24930cb2f56f6d9cd10ffcb031e27ea4157a-wasm-binaries.tbz2 from https://storage.googleapis.com/webassembly/emscripten-releases-builds/linux/1eec24930cb2f56f6d9cd10ffcb031e27ea4157a/wasm-binaries.tbz2, 349224945 Bytes
Unpacking '/home/nitt/Projects/WASM2/emsdk/zips/1eec24930cb2f56f6d9cd10ffcb031e27ea4157a-wasm-binaries.tbz2' to '/home/nitt/Projects/WASM2/emsdk/upstream'
Done installing tool 'releases-1eec24930cb2f56f6d9cd10ffcb031e27ea4157a-64bit'.
Done installing SDK 'sdk-releases-1eec24930cb2f56f6d9cd10ffcb031e27ea4157a-64bit'.
nitt@nitt-laptop:~/Projects/WASM2/emsdk$ ./emsdk activate latest
Resolving SDK alias 'latest' to '3.1.31'
Resolving SDK version '3.1.31' to 'sdk-releases-1eec24930cb2f56f6d9cd10ffcb031e27ea4157a-64bit'
Setting the following tools as active:
   node-14.18.2-64bit
   releases-1eec24930cb2f56f6d9cd10ffcb031e27ea4157a-64bit

Next steps:
- To conveniently access emsdk tools from the command line,
  consider adding the following directories to your PATH:
    /home/nitt/Projects/WASM2/emsdk
    /home/nitt/Projects/WASM2/emsdk/node/14.18.2_64bit/bin
    /home/nitt/Projects/WASM2/emsdk/upstream/emscripten
- This can be done for the current shell by running:
    source "/home/nitt/Projects/WASM2/emsdk/emsdk_env.sh"
- Configure emsdk in your shell startup scripts by running:
    echo 'source "/home/nitt/Projects/WASM2/emsdk/emsdk_env.sh"' >> $HOME/.bash_profile

El último comando, "fuente ./emsdk_env.sh". Garantiza que la ruta de la herramienta del compilador emcc Emscripten esté configurada y que pueda usarla para compilar código.

#Output

nitt@nitt-laptop:~/Projects/WASM2/emsdk$ source ./emsdk_env.sh
Setting up EMSDK environment (suppress these messages with EMSDK_QUIET=1)
Adding directories to PATH:
PATH += /home/nitt/Projects/WASM2/emsdk
PATH += /home/nitt/Projects/WASM2/emsdk/upstream/emscripten
PATH += /home/nitt/Projects/WASM2/emsdk/node/14.18.2_64bit/bin

Setting environment variables:
PATH = /home/nitt/Projects/WASM2/emsdk:/home/nitt/Projects/WASM2/emsdk/upstream/emscripten:/home/nitt/Projects/WASM2/emsdk/node/14.18.2_64bit/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin
EMSDK = /home/nitt/Projects/WASM2/emsdk
EMSDK_NODE = /home/nitt/Projects/WASM2/emsdk/node/14.18.2_64bit/bin/node
nitt@nitt-laptop:~/Projects/WASM2/emsdk$ 

Ahora, necesitamos generar el código wasm ejecutando el siguiente comando.

emcc hello-geekflare.c -o hello-geekflare.js
#Output

nitt@nitt-laptop:~/Projects/WASM2$ emcc hello-geekflare.c -o hello-geekflare.js
shared:INFO: (Emscripten: Running sanity checks)
cache:INFO: generating system asset: symbol_lists/1c683af19e290d0b5ca7a8747d74a76f63dcb362.txt... (this will be cached in "/home/nitt/Projects/WASM2/emsdk/upstream/emscripten/cache/symbol_lists/1c683af19e290d0b5ca7a8747d74a76f63dcb362.txt" for subsequent builds)
cache:INFO:  - ok
nitt@nitt-laptop:~/Projects/WASM2$ dir
emsdk  hello-geekflare.c  hello-geekflare.js  hello-geekflare.wasm
nitt@nitt-laptop:~/Projects/WASM2$ 

Como puede ver, obtiene una salida de "hello-geekflare.js" y hello-geekflare.wasm. Puede verificar los archivos ejecutando dir en el directorio del proyecto.

Ambos archivos son esenciales. hello-geefklare.wasm contiene el código compilado. El archivo hell-geefklare.js, por otro lado, tiene el JavaScript necesario para ejecutarlo. Como Emscripten admite la ejecución web y node.js, podemos probarlo con Node.

node hello-geekflare.js
#Output

nitt@nitt-laptop:~/Projects/WASM2$ node hello-geekflare.js
Hello, GeekFlare! 
nitt@nitt-laptop:~/Projects/WASM2$ 

Si desea verlo ejecutarse en la web, puede generar el archivo HTML con Emscripten. Para hacerlo, ejecute el siguiente comando.

emcc hello-geekflare.c -o hello-geekflare.html
#Output

nitt@nitt-laptop:~/Projects/WASM2$ emcc hello-geekflare.c -o hello-geekflare.html
nitt@nitt-laptop:~/Projects/WASM2$ 

Para ejecutar el archivo HTML, puede usar Python 3 HTTPServer ejecutando el siguiente comando.

python3 -m HTTP.servidor 8000

Ahora, ve a http://localhost:8000/hello-geekflare.html para ver la salida.

Nota: La mayoría de los sistemas vienen preinstalados con Python. De lo contrario, puede instalarlo fácilmente antes de intentar ejecutar el servidor Python3.

Using JavaScript API to Work With WASM

Esta sección analizará más de cerca la API WASM de JavaScript. Con él, aprenderemos a cargar código WASM y ejecutarlo. Pero primero, veamos el código a continuación.

fetch('hello-geekflare.wasm').then( response =>
   response.arrayBuffer())
   .then (bytes =>
       WebAssembly.instantiate(bytes))
       .then(result=>
           alert(result.instance.exports.answer()))

El código anterior utiliza las siguientes API de JavaScript.

  • buscar () API del navegador
  • WebAssembly.instantiate

Además de estos, hay otras API que vale la pena mencionar. Éstos incluyen:

  • WebAssembly.compile
  • WebAssembly.instancia
  • WebAssembly.instantiate
  • WebAssembly.instantiateStreaming

buscar () API del navegador

La API fetch() carga el recurso de red .wasm. Si está intentando cargarlo localmente, debe deshabilitar el uso compartido de recursos de origen cruzado para cargar el recurso de red. De lo contrario, puede usar un servidor de nodos para que lo haga por usted. Para instalar y ejecutar un servidor de nodos, ejecute el siguiente comando.

sudo apt install npm

A continuación, ejecute el siguiente comando para ejecutar el servidor.

npx http-server -o
#Output

http-server version: 14.1.1

http-server settings: 
CORS: disabled
Cache: 3600 seconds
Connection Timeout: 120 seconds
Directory Listings: visible
AutoIndex: visible
Serve GZIP Files: false
Serve Brotli Files: false
Default File Extension: none

Available on:
  http://127.0.0.1:8080
  http://192.168.0.107:8080
Hit CTRL-C to stop the server
Open: http://127.0.0.1:8080

[2023-01-28T19:22:21.137Z]  "GET /" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.70"
(node:37919) [DEP0066] DeprecationWarning: OutgoingMessage.prototype._headers is deprecated
(Use `node --trace-deprecation ...` to show where the warning was created)
[2023-01-28T19:22:21.369Z]  "GET /favicon.ico" "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/109.0.0.0 Safari/537.36 Edg/109.0.1518.70"
[2023-01-28T19:22:21.369Z]  "GET /favicon.ico" Error (404): "Not found"

Se abrirá el navegador web donde podrá ver todos los archivos de su proyecto.

Ahora abra hello-geefklare.html y ejecute las herramientas del desarrollador web. Allí, abre la consola y escribe lo siguiente.

buscar(“hola-geekflare.wasm”);

Devolverá la siguiente promesa.

#Output

Promise {<pending>}
[[Prototype]]: Promise
[[PromiseState]]: "fulfilled"
[[PromiseResult]]: Response
body: (...)
bodyUsed: false
headers: Headers {}
ok: true
redirected: false
status: 200
statusText: "OK"
type: "basic"
url: "http://127.0.0.1:8080/hello-geekflare.wasm"
[[Prototype]]: Response

También puede escribir el siguiente script y ejecutarlo a través de HTML.

Para ejecutar sus módulos wasm en el servidor, debe usar el siguiente código en Node.js.

const fs = require('fs');
const run = async() => {
   const buffer = fs.readFileSync("./hello-geekflare.wasm");
   const result = await WebAssembly.instantiate(buffer);
   console.log(result.instance.exports.answer());
};

run();

Sugerimos leer API de JavaScript de WebAssembly Documentación para saber más al respecto.

JavaScript Vs. WASM

Para comprender la relación entre WASM y JavaScript, también debemos compararlos. Básicamente, WASM es más rápido y tiene un formato binario para la compilación de destino, mientras que JavaScript es un lenguaje de alto nivel. El código binario de WASM dificulta el aprendizaje, pero hay formas de trabajar con WASM de manera eficiente.

La diferencia clave entre WASM y JavaScript incluye lo siguiente:

  • WASM es un lenguaje compilado, mientras que JS es un lenguaje interpretado. El navegador debe descargar y analizar JavaScript en tiempo de ejecución, mientras que el código WASM está listo para ejecutarse con su código precompilado.
  • WebAssembly es un lenguaje de bajo nivel. Por el contrario, JavaScript es un lenguaje de alto nivel. Al ser de alto nivel, es fácil trabajar con JS. Sin embargo, WASM, al ser de bajo nivel, puede ejecutarse mucho más rápido que JavaScript.
  • Por último, JavaScript se beneficia de su gran comunidad. Entonces, si está buscando una mejor experiencia de desarrollo, JS es una opción obvia. WebAssembly, por otro lado, es relativamente nuevo y, por lo tanto, carece de recursos.

Como desarrollador, no tiene que preocuparse por elegir uno. Esto se debe a que tanto JS como WASM trabajan juntos y no uno contra el otro.

Por lo tanto, si está escribiendo una aplicación de alto rendimiento, es posible que desee usar WebAssembly para codificar solo las partes que necesitan rendimiento. La API de JavaScript puede ayudarlo a obtener y usar módulos WASM directamente en su código JavaScript.

Consideraciones Finales:

Al final, WebAssembly es un gran compañero de JavaScript. Invita a los desarrolladores a crear aplicaciones de alto rendimiento en la web y fuera de ella. Además, lo hace sin intentar reemplazar JavaScript. 

Sin embargo, ¿WASM se convertirá en un paquete completo y reemplazará a JavaScript? Bueno, eso es probable, no posible, considerando los objetivos de WebAssembly. Sin embargo, la idea de que WebAssembly reemplace a JavaScript en el futuro no es del todo refutable.

A continuación, echa un vistazo a los mejores Bibliotecas de interfaz de usuario de JavaScript (JS) para crear aplicaciones modernas.

Gracias a nuestros patrocinadores
Más lecturas interesantes sobre el desarrollo
Impulse su negocio
Algunas de las herramientas y servicios para ayudar a que su negocio crezca.
  • Invicti utiliza Proof-Based Scanning™ para verificar automáticamente las vulnerabilidades identificadas y generar resultados procesables en cuestión de horas.
    Prueba Invicti
  • Web scraping, proxy residencial, administrador de proxy, desbloqueador web, rastreador de motores de búsqueda y todo lo que necesita para recopilar datos web.
    Prueba Brightdata
  • Semrush es una solución de marketing digital todo en uno con más de 50 herramientas en SEO, redes sociales y marketing de contenido.
    Prueba Semrush
  • Intruder es un escáner de vulnerabilidades en línea que encuentra debilidades de ciberseguridad en su infraestructura, para evitar costosas filtraciones de datos.
    Intente Intruder