How to call Rust from JS and back?
Asked Answered
A

1

8

I'm trying to adapt the game of life tutorial to call user-defined JS (instead of alert) from Rust:

index.js:

import * as wasm from "testing-wasm";

export const jsfunc = () => {
  console.log("jsfunc called");
};

// Call Rust from JS. This function will call `jsfunc`, declared above.
wasm.rustfunc();

lib.rs:

mod utils;

use wasm_bindgen::prelude::*;

// When the `wee_alloc` feature is enabled, use `wee_alloc` as the global
// allocator.
#[cfg(feature = "wee_alloc")]
#[global_allocator]
static ALLOC: wee_alloc::WeeAlloc = wee_alloc::WeeAlloc::INIT;

#[wasm_bindgen(module = "/www/index.js")]
extern "C" {
    fn jsfunc();
}

#[wasm_bindgen]
pub fn rustfunc() {
    // call JS
    jsfunc();
}

wasm-pack build runs fine. But running the web project (npm run start) can't resolve the import anymore:

ERROR in ../pkg/snippets/testing-wasm-8ea926e8de57779d/www/index.js
Module not found: Error: Can't resolve 'testing-wasm' in '/Users/ischuetz/dev/ct-an/testing-wasm/pkg/snippets/testing-wasm-8ea926e8de57779d/www'
 @ ../pkg/snippets/testing-wasm-8ea926e8de57779d/www/index.js 1:0-37 7:0-13
 @ ../pkg/testing_wasm_bg.wasm
 @ ../pkg/testing_wasm.js
 @ ./index.js
 @ ./bootstrap.js

It works before introducing the circular dependency.

Any ideas? I also found import_js in wasm-bindgen but there's no direct call to Rust from JS.

Auramine answered 25/11, 2020 at 7:31 Comment(0)
B
2

in your Cargo.toml file add this:

[lib]
# if you want to integrate your rust code with javascript we use cdylib
crate-type=["cdylib"]

since you are using wasm-bindgen and wee_alloc and I assume it is already in your .toml file:

[dependencies]
wasm-bindgen="0.2.63"
wee_alloc="0.4.5"

When you build your code, pkg folder is created which includes glue javascript code wasm code. Now you need to get this pkg folder into the node modules. To do so, you have to link it to your javascript project's package.json:

"dependencies": {
    // your path to ../pkg might be different
    "rust_project": "file:../pkg",
  },

Then in your javascript project directory, npm install. You will see that rust_project module is in your node_modules directory.

In your javascript file:

import rustfunc from "rust_project";

Now you can call your function

Biaxial answered 4/2, 2022 at 20:25 Comment(2)
It's a good answer if you're talking about nodejs. Is it possible to do this in the browser?Ecosystem
@Ecosystem in order to use it for browser the only difference is the building command wasm-pack build --target web . eventually wasm-pack creates a module and then you need to load this module in your project through package.json dependenciesBiaxial

© 2022 - 2024 — McMap. All rights reserved.