Search code examples
javascriptrustwebassemblywasm-bindgenrust-wasm

Using a function from a wasm module in JavaScript


I've decided to learn Rust alongside Web Assembly to get into more cloud computing. I'm trying to make a Rust app that connects to a Redis cache and increments a value each time a function is called. I then want to export that function with the wasm-bindgen to use it with JavaScript in a website that will call the function each time the website is refreshed and display the value on screen. Here is my current rust code:

use redis::{Client, Commands};
use wasm_bindgen::prelude::*;

#[wasm_bindgen]
pub fn increment_counter() -> i32 {
    let client: Client = Client::open("redis://127.0.0.1/").unwrap();
    let mut con: redis::Connection = client.get_connection().unwrap();
    let key: &str = "counter";
    let value: i32 = con.get(key).unwrap_or(0);
    let new_value: i32 = value + 1;
    let _: () = con.set(key, new_value).unwrap();
    new_value
}

and here is my HTML & JS:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>Increment Value Example</title>
  </head>
  <body>
    <h1>Current value:</h1>
    <div id="counter"></div>
    <script type="module">
import { increment_counter } from "./pkg/increment.js";

const counterElement = document.getElementById("counter");

function updateCounter() {
  const count = increment_counter();
  counterElement.textContent = count;
}

updateCounter();

    </script>
  </body>
</html>

I've been compiling the rust code with wasm-pack build --target web and trying to use the increment.js file that makes. I host the server with http-server from npm but get this error in the browser:

Uaught SyntaxError: The requested module './pkg/increment.js' does not provide an export named 'increment_counter' (at (index):11:10)

But I think the rust code does export the function correctly with wasm-bindgen and I get no errors/warnings from the compiler so I am really confused as to where I am going wrong.

Any help is much appreciated!


Solution

  • wasm-pack build --target web
    

    this will create pkg folder and inside you will javascript file. pkg is a different module, your front end is a different module. to reach out to pkg, i think you should add it to the package.json inside your front end project.

    "dependencies": {
        // what ever the name of the .js file in pkg directory
        "increment": "file:../pkg",  
      },
    

    in your front end

    // note that in dependencies I named the module as increment
    // all pub variables decorated with #[wasm_bindgen] can be imported
    import init, { increment_counter } from "increment";
    
    init().then((wasm) => {
       // implement logic here
    });