trunk icon indicating copy to clipboard operation
trunk copied to clipboard

How to call functions generated by wasm_bindgen?

Open flosse opened this issue 3 years ago • 1 comments

Let's say I want to call this function from JS:

#[wasm_bindgen]
pub fn send_example_to_js() -> JsValue {
     // ...
}

in the index.html added this:

 <link data-trunk rel="inline" href="main.js" />

and in main.js I want to use the fn:

import { send_example_to_js } from "index";

let example = send_example_to_js();

but how to access the "index"?

flosse avatar Jul 06 '21 14:07 flosse

@flosse hello! Thanks for opening the issue. This is actually a part of wasm-bindgen's functionality as described here: https://rustwasm.github.io/wasm-bindgen/reference/js-snippets.html You may need to use this pattern to "register" your Rust function as a callable for JS using the pattern described here https://rustwasm.github.io/wasm-bindgen/reference/passing-rust-closures-to-js.html

Overall, I would review the web-sys docs. There is a lot of functionality there. Keep me posted.

thedodd avatar Jul 28 '21 00:07 thedodd

Perhaps what @flosse is asking for is to some extent addressed in this other, more recent issue: https://github.com/thedodd/trunk/issues/298. In any case, they seem related.

Since it's my first comment here, I'd like to thank you @thedodd for creating and maintaining Trunk. It makes using Rust for web development so much easier!

tad-lispy avatar Mar 05 '23 10:03 tad-lispy

For anyone that might come across this issue, the pertinent wasm-bindgen docs for this are here: https://rustwasm.github.io/docs/wasm-bindgen/reference/types/exported-rust-types.html

The best approach to solving this problem entirely in Trunk as of v0.16 is as follows:

  • Add these lines to your index.html:
 <link data-trunk rel="copy-file" href="src/call-rust.js" />
 <script src="./call-rust.js" type="module"></script>
  • The call-rust.js script should look something like this:
import init, {call_rust_from_js} from './app.js';
async function run() {
  await init();
  call_rust_from_js();
}
run();
  • Then in your main trunk app code, just export that call_rust_from_js function:
#[wasm_bindgen]
pub fn call_rust_from_js() {
    // Do some rust stuff.
}

That example works end to end on Trunk 0.16. The main pitfall to watch out for:

  • File hashing will complicate this. You can use a hook to grab the hash info and add it to your JS imports, or perhaps some other more exotic approach. You can also just disable hashing.

In the future, it would be great to add a dedicated Trunk lib type, so that we can have a Rust lib compiled and exported as a wasm lib for JS to call.

thedodd avatar May 04 '23 00:05 thedodd

Thanks @thedodd! Currently I'm quite happy with the pattern_script solution provided by @usagi in the other issue. Could you explain why this is better? Also, could you provide an example of "using a hook to grab the hash info and adding it to your JS imports"? Hashing seems very useful for preventing cache issues so I'd rather not disable it.

tad-lispy avatar May 08 '23 14:05 tad-lispy