New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WASM bundles fail when loaded via `file://` URLs #7918

Open
bspeice opened this Issue Aug 19, 2018 · 7 comments

Comments

Projects
None yet
5 participants
@bspeice

bspeice commented Aug 19, 2018

Bug report

What is the current behavior?
Electron apps fail to load WASM code because WASM bundles served via file URL's aren't allowed to be loaded via instantiateStreaming (specifically because MIME application/wasm must be set.

If the current behavior is a bug, please provide the steps to reproduce.
No configuration is specifically necessary, but I've included a reproducing project at this git repo. To run:

yarn install
./build.sh
yarn start

Running will require a recent Rust nightly build, but I'm happy to add the bundle files if necessary to skip that step.

What is the expected behavior?
Webpack would detect that file URLs are not eligible for inclusion via instantiateStreaming and prioritize filling the arrayBuffer and instantiateing that instead.

Please note that I can specifically reproduce the correct behavior by snipping out the else if(...) WebAssembly.instantiateStreaming branch. I'm not sure what the right way of fixing this is, but I'm happy to work on a PR if someone can point me in the right direction.

Other relevant information:
webpack version: 4.16.5
Node.js version: 8.10
Operating System: Linux
Additional tools: Rust nightly


Alright, some updates after I spent more time looking at this: the actual URL request goes to ".wasm", so adding checks for "./" or "file://" don't fix this specific issue (though may not be a bad idea in general). Is this something that should potentially have a config value added instead, where we can disable streaming load?

@xtuc

This comment has been minimized.

Member

xtuc commented Aug 20, 2018

I think that's something that browser should change. arrayBuffer + instantiate too has many disadvantages.

I'm not very familiar with Electron, could we load the wasm module using node and fs?

@xtuc

This comment has been minimized.

Member

xtuc commented Aug 20, 2018

Btw here's a previous discussion: WebAssembly/design#1200

@bspeice

This comment has been minimized.

bspeice commented Aug 21, 2018

I'm admittedly totally unfamiliar with fs in node - my expectation is that you could load just fine, but you'd still have issues with the instantiateStreaming support. Some people I've talked with recommended effectively spinning up a static file server in-process to load the resource bundles (with appropriate MIME types) but this strikes me as a bit strange - I don't particularly want to host a server inside the electron app.

@schmidtk

This comment has been minimized.

schmidtk commented Aug 30, 2018

Emscripten's boilerplate to load WebAssembly modules handles this situation with a graceful fallback to ArrayBuffer instantiation. A similar approach could be applied here in webpack.

I tested this solution in the webpack output and it solved my problem in Electron. If anyone with more (any) webpack contribution experience would like to fix this via PR I would be forever grateful, otherwise I may be able to make time to take a crack at it.

@sokra

This comment has been minimized.

Member

sokra commented Sep 2, 2018

Yep send a PR

bspeice added a commit to bspeice/webpack that referenced this issue Sep 3, 2018

@bspeice

This comment has been minimized.

bspeice commented Sep 3, 2018

I've started a PR, but it could use some assistance (I'm not sure what exactly is or would be failing in the integration tests). If anyone's able to help that would be great, otherwise feel free to use it as a starting point.

@xtuc

This comment has been minimized.

Member

xtuc commented Sep 3, 2018

Thanks @bspeice for the PR.

Maybe we can override window.fetch to throw an error only the first call, so the fallback will still work.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment