In this post, we will convert our javascript code to web assembly.
So, first let's setup our environment.
Local Environment Setup
1) Javy - A JavaScript to WebAssembly toolchain. It takes your JavaScript code, and executes it in a WebAssembly embedded JavaScript runtime.
In your terminal/shell clone the javy repository as follows:
git clone https://github.com/Shopify/javy.git
Now, navigate to javy by executing cd javy
Here, you have to install all the build and development dependencies in javy directory from here.
After all the dependencies are installed, run make
. You should now have access to the executable in target/release/javy
Alternatively you can run make && cargo install --path crates/cli
. After running the previous command you'll have a global installation of the executable.
2) Wasmtime - A small and efficient runtime for WebAssembly & WASI.
It can be installed by
curl https://wasmtime.dev/install.sh -sSf | bash
Code
Create a javascript file named index.js and write js code for fibonacci number as-
We need to call our main function i.e., fibonacci in our case, from the shopify object.
//Simple Program to calculate Fibonacci Sequence of an Integer Input
function fibonacci(num){
var a = 1, b = 0, temp;
while (num >= 0){
temp = a;
a = a + b;
b = temp;
num--;
}
console.log("Fibonacci Term is ",b);
}
var Shopify = {
main: fibonacci
};
Compiling our code
1) Convert javascript code to wasm binary
javy index.js -o index.wasm
2) Execute wasm file, using following command
echo "10" | wasmtime run index.wasm
You will see the output:
References - https://www.wasm.builders/deepanshu1484/javascript-and-wasi-24k8
Top comments (11)
Thank you, @gunjan_0307 . Are there any good reason to use this approach? Because if you want to run JavaScript without a browser, you can just use NodeJS.
That's a good question, @webcoder. So one key reason would be security. Since WebAssembly uses a sandbox model, you can prevent a malicious or buggy JavaScript application from compromising the host. Other reasons might be performance and portability. Depending on the application, it might be faster to run the WebAssembly code directly (no Nodejs overhead). As for portability, you might run this same application anywhere without recompilation (server, client, edge, IoT, whatever).
@nick Thanks for so good explanation. :)
For me, it was simply getting byte code off my JavaScript files, it's like dream comes true.
What is the issue about this errors follow your article.
Toolchains:
There has been some issue with the recent release of the Javy Toolchain as pointed by @deepanshu1484 i.e., There has been some changes in the way in order to make it work on Wasmtime and we do not require the use of msgpack-tools anymore and thus the process has even become more convenient now.
I have update this post, please have a look.
Thanks.
Explained by:
wasm.builders/deepanshu1484/javasc...
Yes I also followed his demo 😀
this is super exciting stuff - any idea why
wasm-opt
can hardly shave off anything in terms of size? (getting 992k vs. 982k for a very simple js file, essentially just a bit of math andconsole.log
)probably because of the bundled runtime (which includes a gc)
Unfortunately for me, Javy explicitly doesn't support Node.
My problem is I'm using a js library in the browser. This lib was specifically built for node, but later added support to run in browser via a patchwork of polyfills. The lib does run OK in node. Not blazingly fast, but acceptable, while in the browser the same script (running in a web worker) will take way longer for small data, and hang indefinitely with large data (large data that wasn't a problem in Node).
So I'm hoping I can compile the script from Node to WASM and ship it to the browser and get the same performance as if it were running in Node.
As someone new to WASM, does this sound sensible?