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.
- WebAssmebly para principiantes Parte 1: Introducción a WASM
- WebAssembly para principiantes Parte 2: objetivos, conceptos clave y casos de uso
- WebAssembly para principiantes Parte 3: Cómo funciona la portabilidad y la seguridad de WASM
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.