Closed nicolasmelo1 closed 3 years ago
Hm sorry it's been quite some time since I looked at this example. It could be an issue with the example, but can you track down where the fetch of the wasm is happening? Perhaps you can work backwards from there to figure out where the issue is and what's not requesting the JS instead?
Hello, thanks from the response in advance.
So from what i saw
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
on this line in init()
function is the exact line the where it gets the route to the .wasm file and here
wasm2js.js
:
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
input = fetch(input);
}
is where it fetches for the .wasm file. i've tried changing this
wasm2js.js
:
input = import.meta.url.replace(/\.js$/, '_bg.wasm');
to this
wasm2js.js
:
input = import.meta.url.replace(/\.js$/, '_bg.js');
but still it didn't work as expected. Because it's still trying to create a WebAssembly intance in load
, as you can see in load function in the js output it doesn't handle when there is no WebAssembly available in the browser
wasm2js.js
:
async function load(module, imports) {
if (typeof Response === 'function' && module instanceof Response) {
if (typeof WebAssembly.instantiateStreaming === 'function') {
try {
return await WebAssembly.instantiateStreaming(module, imports);
} catch (e) {
if (module.headers.get('Content-Type') != 'application/wasm') {
console.warn("`WebAssembly.instantiateStreaming` failed because your server does not serve wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\n", e);
} else {
throw e;
}
}
}
const bytes = await module.arrayBuffer();
return await WebAssembly.instantiate(bytes, imports);
} else {
const instance = await WebAssembly.instantiate(module, imports);
if (instance instanceof WebAssembly.Instance) {
return { instance, module };
} else {
return instance;
}
}
}
on the '.js' file created by wasm2js it imports the wbg
module, but since this module doesn't exist, i haven't found a way to make this file work with the wasm2js.js
file outputed by the wasm-pack build
wasm2gs_bg.js
:
import { __wbindgen_throw } from 'wbg';
// ... rest of code generated by wasm2js
Oh the wasm2js support was intended to be used with ES modules, I don't believe it works with --target web
or no-modules
since they use the WebAssembly
object for instantiation which won't work.
That's actually strange because on the example in the build.sh
on the second line we compile targeting to --target web
But anyway, i've tried running
wasm-pack build
And it gives me two .js files:
wasm2js.js
- which just exports wasm2js_bg.js
(so it has only two lines)wasm2js_bg.js
- which doesn't initialize WebAssembly. (that's just what i needed)Then i run the following command to create a new .js file from the wasm
wasm2js ./pkg/wasm2js_bg.wasm -o ./pkg/wasm2js_bg1.js
in the wasm2js_bg1.js
file we end up with
import { __wbindgen_throw } from './wasm2js_bg.js';
// ... rest of code generated by wasm2js
and in wasm2js_bg.js
which was generated by wasm-pack build i've changed:
import * as wasm from './wasm2js_bg.wasm';
to
import * as wasm from './wasm2js_bg1.js'; // file generated by wasm2js command
and now we end up with a circular import.
For my use case i was able to prevent this from happening by removing this import in wasm2js_bg.js
and using require('./wasm2js_bg1.js')
whenever wasm
was being called in wasm2js_bg.js
So i've changed this:
wasm2js_bg.js
export function greet() {
var ret = wasm.greet();
return Data.__wrap(ret);
}
to this
wasm2js_bg.js
export function greet() {
var ret = require('./wasm2js_bg.js').greet();
return Data.__wrap(ret);
}
But i don't think this is a good solution, especially if the idea is to target browsers which doesn't support require()
I've got the same issue, also with same MO (Rust -> WASM -> JS -> React Native). git@github.com:mvniekerk/brotli-rs2js.git
I'll be following @nicolasmelo1 's example and try get it running.
Summary
Hello, so i'm trying to run wasm in react native and since i cannot run webassembly code directly i thought about creating a wasm file, converting it to JS using wasm2js command and then using the generated file directly. Before testing in the react native ambient i'm making tests directly in the browser and for this case i'm using the wasm2js example provided in the wasm-bindgen examples folder. But following the EXACT steps defined by the example, the wasm2js is STILL fetching the original .wasm file and not using the .js file generated by wasm2js command
Expected Behavior
In reality, if i understood correctly the wasm2js.js should use the
wasm2js_bg.js
file and not thewasm2js_bg.wasm
file. Since some browsers might not support WebAssembly.What happens is that this command in build.sh
sed -i 's/wasm2js_bg.wasm/wasm2js_bg.js/' pkg/wasm2js.js
is doing nothing in the pkg/wasm2js.js file
Additional Details
So to make it absolutely clear here what i'm trying to do is:
1 - Create a rust package that should be used both by the browser and the mobile version of my app 2 - On the browser i'll use the .wasm directly with webpack 3 - On the mobile i'll convert the .wasm to JS so i just use JS code instead of .wasm code. (performance penalties are known but the core idea here is to be possible to use my rust functions already created without needing to rewrite it in javascript) 4 - On step 3 i'm not testing this already in the app, but instead i'm making tests directly in the browser, i want to run the example code using only the .js files and not fetching the '.wasm' as it is doing by default
STEP 4 is basically what i need to reproduce and facing issues with.
I've tried running the wasm2js generated .js file directly, the problem is that they import 'wbg' which is defined in the wasm2js.js file, so it's not working.