Birch-san / box2d-wasm

Box2D physics engine compiled to WebAssembly. Supports TypeScript and ES modules.
265 stars 21 forks source link

WASM streaming compile failed #1

Closed joex92 closed 3 years ago

joex92 commented 3 years ago

I'm using this code to initialize Box2D similar to what @Kripken did here in an example

<script language="javascript" type="text/javascript" src="node_modules/box2d-wasm/build/Box2D.js"></script>
    <script language="javascript" type="text/javascript">  
        if (!Box2D) Box2D = (typeof Box2D !== 'undefined' ? Box2D : null) || Module; 
        Box2D().then(function(r){
            Box2D = r;
            Module = Box2D;
            if(document.readyState === "complete"){
                afterDocumentLoaded()
            } else {
                window.onload = afterDocumentLoaded
            }
        });
        const afterDocumentLoaded = function(){
            using(Box2D, "b2.+");
        };
    </script>
    <script language="javascript" type="text/javascript" src="libs/box2d.js/helpers/embox2d-helpers.js"></script>

So I'm getting this

> Box2D.js:58 wasm streaming compile failed: TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.

> Box2D.js:58 falling back to ArrayBuffer instantiation

I'm not running this local web server with npm, because I still don't get npm that much...

joex92 commented 3 years ago

I'm new to WASM in general, so I'm using what I find in examples/demos...

Birch-san commented 3 years ago

Looks like it tried to download Box2D.wasm, but the server delivered a file with the wrong MIME type.

Check the "network" tab in your browser DevTools — is there a failed download for Box2D.wasm?
Or, did the download succeed, but the Response Header indicates an incorrect MIME type?

Server setup advice is detailed here:
https://emscripten.org/docs/compiling/WebAssembly.html#web-server-setup

For example, if you're using an Apache webserver, you can create a .htaccess in the same directory with the following directive:

AddType application/wasm .wasm
joex92 commented 3 years ago

ok thanks, I'll check the emscripten page, but why is it downloading it? isn't the *.wasm already in there? image

Birch-san commented 3 years ago

you've tag-loaded Box2D.js into the webpage, which is correct:

<script language="javascript" type="text/javascript" src="node_modules/box2d-wasm/build/Box2D.js"></script>

But this just gets you the first file, Box2D.js.

Box2D.js includes some bootstrapping code that attempts to fetch Box2D.wasm, which as you've demonstrated, is a separate file.

Box2D.wasm benefits from being a separate file, because this enables your server to serve it differently — it can be served with the MIME type application/wasm, which tells your browser it's fine to apply streaming compilation to it.

joex92 commented 3 years ago

ok, so do I have to tag-load Box2D.wasm into the webpage in the html file? is .htaccess the only way to set the MIME type? I've tried and for some reason my local server doesn't seem to load the .htaccess file... I'm using a VScode web server extension to start a live web server...

Birch-san commented 3 years ago

.htaccess is an Apache httpd concept.

I wouldn't be surprised if there were no way to do this with VSCode web server, but worth reading their documentation.

Tag-loading Box2D.wasm into the webpage won't help. Box2D.js intends to initiate the response itself. Moreover, tag-loading won't influence the MIME type.

I really recommend looking up how to serve the files using a more ubiquitous approach, like Apache httpd, nginx or Node.js express.

joex92 commented 3 years ago

I still don't get how Node.js server works so I'm going to try apache httpd... anyways, isn't there a way to make the Box2D.js file to read the *.wasm file in the directory instead of fetching it from the server?

Birch-san commented 3 years ago

There's no way to make Box2D.js read Box2D.wasm from the filesystem, because of the browser's security model. Browser doesn't have access to your filesystem, only your network. Hence it has to use browser fetch() API instead.

Birch-san commented 3 years ago

Closing on the basis that this is an asset-serving question related to Emscripten/WebAssembly rather than being an error in box2d-wasm.

Refer to the new demos for examples of how to serve the content.