node-inline-assets icon indicating copy to clipboard operation
node-inline-assets copied to clipboard

Wasm support?

Open Boscop opened this issue 7 years ago • 9 comments

Does this support the inlining of .wasm files? It would be very useful for building standalone web apps! :)

Boscop avatar May 22 '18 18:05 Boscop

Currently it does not know anything about .wasm files? How should they be handled during inlining? What is the mechanism to inline .wasm files? How are they referenced at all officially?

rse avatar Jun 24 '18 10:06 rse

Sorry for the delay, I was busy with other things..

Wasm can be inlined as a Uint8Array: https://dzone.com/articles/webassembly-wasmfiddle-and-inline-webassembly-modu

Related: https://github.com/xtuc/inline-wast https://github.com/WebAssembly/design/issues/1129#issuecomment-327591545 https://github.com/WebAssembly/design/issues/1206

I'm really looking forward to being able to inline .wasm files with this inline-assets cli tool. My use case is: I'm embedding a web-based GUI into my Rust application and show it in an embedded browser (using web-view). I'm writing the frontend in Rust using yew and compiling to WebAssembly (using cargo-web). Since I have to pass the whole frontend as a single urlencoded html page to the embedded web-view (if I don't want to serve it from a local server (which requires searching for a free port etc.)), I have to inline all assets into the index.html page. You can see my current pipeline for the Todo PureScript example here: https://github.com/Boscop/web-view/blob/master/examples/todo-ps/package.json#L10 In this example, after building the app.js I do inline-assets --htmlmin --cssmin index.html dist/bundle.html, then I embed it like this: https://github.com/Boscop/web-view/blob/69519d102bedf16ec42d6a8f73f044323270bacc/examples/todo-purescript.rs#L14 I want to do inline all assets similarly (including my frontend .wasm file) when writing the frontend in Rust..

(Now you may be thinking "but IE11's MSHTML engine doesn't support WebAssembly". Well, there's another crate that uses Edge, and we are probably going to unify both into one crate that uses Edge when it's available but IE as fallback (with the frontend compiled to asm.js then) :)

Boscop avatar Jul 23 '18 18:07 Boscop

@rse Any update on this? :)

Wasm code can be embedded as Uint8Array:

var wasmCode = new Uint8Array([0, 97, 115, 109, 1, 0, 0, 0, 1, 135, 128, 128, 128, 0, 1, 96, 2, 127, 127, 1, 127, 3, 130, 128, 128, 128, 0, 1, 0, 4, 132, 128, 128, 128, 0, 1, 112, 0, 0, 5, 131, 128, 128, 128, 0, 1, 0, 1, 6, 129, 128, 128, 128, 0, 0, 7, 144, 128, 128, 128, 0, 2, 6, 109, 101, 109, 111, 114, 121, 2, 0, 3, 97, 100, 100, 0, 0, 10, 141, 128, 128, 128, 0, 1, 135, 128, 128, 128, 0, 0, 32, 1, 32, 0, 106, 11]);
WebAssembly.compile(wasmCode).then(wasmModule => 
  WebAssembly.instantiate(wasmModule, g_importObject)
).then(instance =>
  alert(instance.exports.add(1, 2))
);

as described in this link: https://dzone.com/articles/webassembly-wasmfiddle-and-inline-webassembly-modu

Boscop avatar Apr 06 '20 04:04 Boscop

I just started a Rust web-view/Yew project, and I have just encountered this issue. I would be very interested in helping with a solution for this problem.

@Boscop The JS code that is generated by Yew and which reads in the wasm file is quite complex. How does one go about generating the Uint8Array from a wasm file? I'd like to see if I can make this work manually.

mbuscemi avatar Apr 13 '20 16:04 mbuscemi

@mbuscemi You just need to read the file into a Vec<u8> with fs::read and print the result like

println!("var wasmCode = new Uint8Array({:?});", fs::read("app.wasm")?);

But this can be optimized by removing the spaces after each comma to reduce the file size of the resulting js code :)

With nodejs you could do:

const fs = require('fs');
const wasmSource = new Uint8Array(fs.readFileSync("app.wasm"));

and then print that.

Boscop avatar Apr 13 '20 17:04 Boscop

@Boscop Thanks for your help! I was able to achieve inline loading of my wasm file like this.

This compiles and runs with a simple GUI, but the very next things I did was try to set up communication between the two layers. I found wasm_bindgen and tried that, but I get JS runtime errors when just including the wasm_bindgen module. The code is here.

mbuscemi avatar Apr 14 '20 10:04 mbuscemi

@mbuscemi Nice to hear that you're making progress. Which errors are you getting? Are you building with cargo web?

Boscop avatar Apr 14 '20 14:04 Boscop

@Boscop I've moved on to trying stdweb to make the calls, which definitely works going from Yew to web-view. Still working on going the other direction.

I don't remember the exact error message. Something about some element of wasm_bindgen not being an object. If you clone my repo and execute make process run you should get it.

mbuscemi avatar Apr 14 '20 14:04 mbuscemi

@Boscop I just pushed some changes to the yew_integration branch. If you want to reproduce that error, you'll want to reset to this commit.

mbuscemi avatar Apr 15 '20 00:04 mbuscemi