How to import an extern JS function when compiling wasm to the nodejs target?

So I'm trying to create a node package by compiling some rust code to webassembly. Since I intend to use this with Node, and no bundler, I'm using

wasm-pack build --target nodejs

This generates a node module that I'm able to require() but I'm still having one issue regarding extern JS functions imports for the webassembly module. I have the following extern functions:

extern "C" {
    fn fetchElmJson(pkg: &str, version: &str) -> String;
    fn listAvailableVersions(pkg: &str) -> Vec<JsValue>;

Unfortunately, when I import my my wasm package in my main JS app, I didn't find anyway to make those extern functions available to the wasm package.

// package.json of my main app
  "name": "elm-deps",
  "dependencies": {
    // "elm-solve-deps-wasm": "file:../pkg" // during dev
    "elm-solve-deps-wasm": "0.1.0"
// index.js
function fetchElmJson(pkg, version) { ... }
function listAvailableVersions(pkg) { ... }
let wasm = require("elm-solve-deps-wasm");
// The solve call fails saying that the function fetchElmJson is not defined.

It makes sense to me that functions defined in my index.html would not be available inside the wasm package I import. But then, how can we make extern function available when compiling the wasm to a node module?

Any idea on how to do this cleanly? I haven't found any clue in the wasm book, the wasm-pack book or the wasm-bindgen book. All other approaches I tried brought their own complications.

It seems so obvious to me to be wanting to have extern functions provided by package users instead of package implementers that I don't understand why there isn't an explanation of how to do this. And that makes me question if what I'm trying to do is right, or if I should do it in a completely different way.

And that makes me question if what I'm trying to do is right, or if I should do it in a completely different way.

That's probably it.

I've just found that it's possible to pass a JS function as argument and call it thanks to the js_sys crate:

pub fn call_js(f: &js_sys::Function) {
    let this = JsValue::null();
    let x = JsValue::from_str("some argument");
    let _ = f.call1(&this, &x);

So it's probably what I want instead of trying to bring "extern" JS functions from user imports.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.