wasm-bindgen: Cannot import an ES6 module after JS snippets change

The b762948456617ee263de8e43b3636bd3a4d1da75 commit has overloaded the meaning of #[wasm_bindgen(module = "...")]. Previously, it has defined an ES6 module import that the JS shim performed and provided to the wasm module. Now it also allows the contents of a JS file to be embedded as a snippet.

The new behavior is problematic when the copied module has imports on its own - the relative paths lose their meaning. I would like to still be able to perform an import to the original path without copying the module.

Unanchored paths (i.e. ones that don’t start with either /, . or ..) still behave the same as before. However, I need to use a relative path starting with ../, which is explicitly disallowed.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 17 (9 by maintainers)

Commits related to this issue

Most upvoted comments

Ok! I’ve pushed up https://github.com/rustwasm/wasm-bindgen/pull/1353 with these changes.

I’m personally a fan of raw_module because then we don’t have to deal with #[wasm_bindgen(raw)] and rationalizing that somehow. If there’s no objection to that I can look to implement this soon!

@alexcrichton Bit of bike shedding: maybe it should be #[wasm_bindgen(raw_module = "./foo.js")] instead?

That could also be useful for importing raw npm modules (like fs, etc.)

I started reading RFC 6 and am very concerned about the section on depending on additional JS files.

Being able to depend on other JS files (and indeed, over a thousand of them not including npm modules) is very important to us.

The strategy that seems to be implied by the RFC is that an additional ‘copy’ of the module and it’s imports will be embedded in the wasm. I may be misunderstanding the implications of this, but if it means what I think that’s a non-starter.

Here’s some of the problems that I see with that:

  1. Increased delivery size - megabytes in our case.
  2. No propagation of ‘module state’. Many of our modules contain private variables which maintain global state that is setup by the javascript as a pre-condition of calling the wasm.

Javascript build processes and their implications are not my strong suit, so please let me know if my concerns are misplaced here.

@alexcrichton In my case, I am creating a web app that is based on the wasm module written in Rust. The wasm module (alongside the wasm-bindgen bindings) is output to the /pkg directory. I have a separate /js directory with some JS code, which I want to reference from the Rust code.

Previously I was using #[wasm_bindgen(module = "../js/module")] in order to import a JS module from Rust. After the snippet change, I had to change the path to "/js/module.js" which was still fine. However, I wanted to import the wasm ES6 module itself from a JS module in order to access the wasm memory. I put import * as wasm from { "../pkg/cratename_bg" } inside the JS module, which would work if it stayed in /js. However, as the snippets are copied to /pkg/snippets/... this relative path no longer works.

I have worked-around this by adding a webpack alias js -> /js. This way I can do #[wasm_bindgen(module = "js/module")] and it works.

In case it matters, the Rust code is in /src, i.e. the Cargo.toml is in the main / directory.