ixx
ixx

Reputation: 32271

How to call Rust from JS and back?

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.

Upvotes: 8

Views: 5225

Answers (1)

Yilmaz
Yilmaz

Reputation: 49180

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

Upvotes: 2

Related Questions