Dans la partie 4 de WebAssembly pour les débutants, nous examinerons de près la collaboration entre WebAssembly et JavaScript.
Ici, vous apprendrez à utiliser WebAssembly dans votre JavaScript. De plus, nous explorerons également l'API JavaScript WebAssembly.
WebAssemebly est une norme ouverte au format binaire qui permet aux développeurs d'exécuter des applications avec des performances natives sur les navigateurs. Si vous ne l'avez pas lu, nous vous suggérons de consulter les parties précédentes de notre guide.
- WebAssmebly pour les débutants Partie 1 : Une introduction à WASM
- WebAssembly pour les débutants, partie 2 : objectifs, concepts clés et cas d'utilisation
- WebAssembly pour les débutants Partie 3 : Fonctionnement de la portabilité et de la sécurité de WASM
Commençons.
Using WebAssembly With JavaScript
Dans notre tutoriel WebAssembly partie 1, nous avons expliqué le fonctionnement de WASM. Pour écrire du code hautes performances pour votre application Web, vous devez utiliser les API et les fonctions WASM dans JavaScript. Nous avons également discuté de la manière dont les frameworks JavaScript pourraient utiliser WASM pour créer des applications hautes performances.
Cependant, vous ne pouvez pas actuellement charger les modules WASM comme les modules ES6 en utilisant le . 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:
- Chargez les octets .wasm dans ArrayBuffer ou un tableau typé.
- Utilisez WebAssembly.Module pour compiler les octets.
- Maintenant, instanciez WebAssembly.Module avec des importations pour obtenir des exportations appelables
Vous devez donc commencer avec le module WASM pré-compilé. Ici, vous avez beaucoup de choix. Vous pouvez utiliser Calme, C/C++, AssemblyScript et même TinyGo(Go) pour écrire votre code et le transformer plus tard en un module .wasm.
Techniquement, WebAssembly est une cible de compilation pour les langages. Cela signifie que vous devrez écrire du code dans la langue de votre choix, puis utiliser le code binaire généré dans l'application (Web ou non Web). De plus, si vous avez l'intention de l'utiliser sur des serveurs, vous devrez utiliser WASI pour l'interface avec les systèmes.
Comme WebAssembly utilise une mémoire linéaire via un tableau extensible, JavaScript et WASM peuvent y accéder de manière synchrone, ce qui vous donne la possibilité d'écrire des applications rapides et riches en fonctionnalités.
WebAssembly and JavaScript Examples
Utilisons des exemples pour savoir comment vous pouvez utiliser WASM avec JavaScript.
Comme mentionné ci-dessus, vous avez besoin d'un module WASM pré-compilé. Pour cet exemple, nous utiliserons Emscripten (C/C++). Comme WASM propose un format binaire hautes performances, nous pouvons exécuter le code généré avec JavaScript ou d'autres langages.
Configuration de l'outil
Comme nous utilisons Emscripten, nous devons obtenir emsdk outil. Cela vous permettra de compiler votre code C/C++ en code .wasm.
Exécutez simplement la commande suivante dans votre terminal. Si vous n'avez pas installé GIT, suivez notre Open Source 101: Système de contrôle de version et Git guide pour le faire.
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$
Dans le emdsk dossier, nous appelons une autre commande pour obtenir la dernière version prête à l'emploi d'Emscripten.
Pour ce faire, vous devez exécuter les commandes suivantes.
./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
La dernière commande, "source ./emsdk_env.sh". Il garantit que le chemin d'accès à l'outil de compilation emcc Emscripten est défini et que vous pouvez l'utiliser pour compiler le code.
#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$
Maintenant, nous devons générer le code wasm en exécutant la commande suivante.
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$
Comme vous pouvez le voir, vous obtenez une sortie de "hello-geekflare.js" et hello-geekflare.wasm. Vous pouvez vérifier les fichiers en exécutant dir dans le répertoire du projet.
Ces deux fichiers sont essentiels. Le hello-geefklare.wasm contient le code compilé. Le fichier hell-geefklare.js, d'autre part, a le JavaScript requis pour l'exécuter. Comme Emscripten prend en charge l'exécution Web et node.js, nous pouvons le tester avec Node.
node hello-geekflare.js
#Output
nitt@nitt-laptop:~/Projects/WASM2$ node hello-geekflare.js
Hello, GeekFlare!
nitt@nitt-laptop:~/Projects/WASM2$
Si vous voulez le voir fonctionner sur le Web, vous pouvez générer le fichier HTML avec Emscripten. Pour ce faire, exécutez la commande suivante.
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$
Pour exécuter le fichier HTML, vous pouvez utiliser Python 3 HTTPServer en exécutant la commande suivante.
python3 -m HTTP.serveur 8000
Maintenant, allez à http://localhost:8000/hello-geekflare.html pour voir la sortie.
Remarque : La plupart des systèmes sont préinstallés avec Python. Sinon, vous pouvez facilement l'installer avant d'essayer d'exécuter le serveur Python3.
Using JavaScript API to Work With WASM
Cette section examinera de plus près l'API JavaScript WASM. Avec lui, nous apprendrons à charger le code WASM et à l'exécuter. Mais d'abord, regardons le code ci-dessous.
fetch('hello-geekflare.wasm').then( response =>
response.arrayBuffer())
.then (bytes =>
WebAssembly.instantiate(bytes))
.then(result=>
alert(result.instance.exports.answer()))
Le code ci-dessus utilise les API JavaScript suivantes.
- fetch() API du navigateur
- WebAssembly.instancier
En dehors de celles-ci, il existe d'autres API à noter. Ceux-ci inclus:
- WebAssembly.compile
- WebAssembly.instance
- WebAssembly.instancier
- WebAssembly.instantiateStreaming
fetch() API du navigateur
L'API fetch() charge la ressource réseau .wasm. Si vous essayez de le charger localement, vous devez désactiver le partage de ressources cross-origin pour charger la ressource réseau. Sinon, vous pouvez utiliser un serveur de nœud pour le faire pour vous. Pour installer et exécuter un serveur de nœud, exécutez la commande suivante.
sudo apt install npm
Ensuite, exécutez la commande suivante pour exécuter le serveur.
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"
Cela ouvrira le navigateur Web où vous pourrez voir tous vos fichiers de projet.
Ouvrez maintenant hello-geefklare.html et exécutez les outils de développement Web. Là, ouvrez la console et tapez ce qui suit.
récupérer ("bonjour-geekflare.wasm");
Il renverra la promesse suivante.
#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
Vous pouvez également écrire le script suivant et l'exécuter via HTML.
Pour exécuter vos modules wasm sur le serveur, vous devez utiliser le code suivant dans 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();
Nous suggérons de lire API JavaScript WebAssembly documentation pour en savoir plus.
JavaScript Vs. WASM
Pour comprendre le compagnonnage entre WASM et JavaScript, nous devons également les comparer. À la base, WASM est plus rapide et a un format binaire pour la compilation cible, tandis que JavaScript est un langage de haut niveau. Le code binaire de WASM rend l'apprentissage difficile, mais il existe des moyens de travailler efficacement avec WASM.
La principale différence entre WASM et JavaScript inclut les éléments suivants :
- WASM est un langage compilé, alors que JS est un langage interprété. Le navigateur doit télécharger et analyser JavaScript au moment de l'exécution, tandis que le code WASM est prêt à s'exécuter avec son code précompilé.
- WebAssembly est un langage de bas niveau. En revanche, JavaScript est un langage de haut niveau. Étant de haut niveau, JS est facile à utiliser. Cependant, WASM étant de bas niveau, il peut s'exécuter beaucoup plus rapidement que JavaScript.
- Enfin, JavaScript bénéficie de sa large communauté. Donc, si vous recherchez une meilleure expérience de développement, JS est un choix évident. WebAssembly, en revanche, est relativement nouveau et manque donc de ressources.
En tant que développeur, vous n'avez pas à vous soucier d'en choisir un. En effet, JS et WASM fonctionnent ensemble et non l'un contre l'autre.
Ainsi, si vous écrivez une application hautes performances, vous souhaiterez peut-être utiliser WebAssembly pour coder uniquement les parties nécessitant des performances. L'API JavaScript peut vous aider à récupérer et à utiliser les modules WASM directement dans votre code JavaScript.
Réflexions finales
Au final, WebAssembly est un excellent compagnon de JavaScript. Il invite les développeurs à créer des applications performantes sur le web et hors web. De plus, il le fait sans essayer de remplacer JavaScript.
Cependant, WASM va-t-il évoluer vers un package complet et remplacer JavaScript ? Eh bien, c'est probablement impossible, compte tenu des objectifs de WebAssembly. Cependant, l'idée de WebAssembly pour remplacer JavaScript à l'avenir n'est pas entièrement réfutable.
Ensuite, découvrez le meilleur Bibliothèques d'interface utilisateur JavaScript (JS) pour créer des applications modernes.