Fixes WASM mimetype for static file server in a production-bundled iOS app
WebAssembly imports don't work correctly on iOS production builds that must serve files within the app instead of over a dev server. This happens because iOS production builds use the file:// protocol to retrieve build files from a static file server, which can strip the MIME type if the file extension isn't recognized by the static file server.
This issue doesn't happen on Android, or in dev iOS builds because both retrieve their build files from a localhost server, which provides the correct MIME type.
This fix defines the WASM file extension for the static file server within the iOS app.
This fix may resolve the WASM MIME type issues listed here: https://github.com/ionic-team/capacitor/issues/774 https://github.com/ionic-team/capacitor/issues/1864 https://github.com/ionic-team/capacitor/issues/4444
Minimum reproduction:
- Install npm package
@emurgo/cardano-serialization-lib-browser - Attempt to import it in a packaged production iOS build (not hosted from a dev server):
await (
await import('@emurgo/cardano-serialization-lib-browser/cardano_serialization_lib')
).default
- The app will throw an error:
Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'
Any update ?
@iamcco Not sure how long it'll take before / if this gets reviewed but if you add the changes I made here to your own info.plist the issue will be resolved.
@iamcco Not sure how long it'll take before / if this gets reviewed but if you add the changes I made here to your own info.plist the issue will be resolved.
Thanks, it works!
Thank you so much, it works!
I can confirm that these added lines solve my wasm issue as well.
Seems straightforward. I'll take a look.
This is a change in the iOS app template, so if this gets merged it would be included in every capacitor app created after the PR gets merged, even if not using WASM. Most users don’t use WASM, so I don’t think this should be part of every app, in any case we should document that this might be needed for using WASM, not even sure if it’s needed for most WASM users as I’ve used WASM in the past without doing this change. If something broke since last time I tested WASM, then we should try to fix it from the code that returns the mime type, not from the template. Can you provide a sample app that reproduces the issue?
I provided minimum conditions needed to reproduce with a specific WASM NPM package installation and import to test with that would trigger the issue.
This issue only affects iOS users on production-packaged builds.
I no longer work at the job where this issue had occurred and my fix was needed so I probably will not also spend time building out a template app to demonstrate reproduction. But I know this is an issue that has affected other WASM users with capacitor and that the fix works.
I don't know how we handle file:// urls in the app - but this is a pretty easy way to support wasm from the filesystem or remote file servers. I'm not sure of the harm of adding it for people that don't need it, but if we wanted to add it using the CLI or further refine the WASM code that could work too. @ItsChaceD had some WASM fixes, but I think they were for HTTP delivered assets.
Sharing my experience in setting up sql.js with capacitor, which worked nicely when the changes proposed above are made to the Info.plist file.
I used vite-plugin-static-copy to copy the wasm file to the build folder using following configuration:
import { defineConfig } from 'vite';
import { viteStaticCopy } from 'vite-plugin-static-copy';
export default defineConfig({
plugins: [
viteStaticCopy({
targets: [{
src: 'node_modules/sql.js/dist/sql-wasm.wasm',
dest: 'wasm-files'
}]
})
]
});
When the app tried to access ${window.location.origin}/wasm-files/sql-wasm.wasm, it received a wrong response MIME type application/octet-stream earlier. I can confirm now that this works in production iOS builds. Thank you @ggaabe for the fix!