I'm using MongoDB Realm / App Services to make a web front end for an existing iOS app.
The standard Realm Web SDK only permits authentication and backend functions, so I am trying to use the preview release of the Web Assembly version ([email protected]) so that I can use device sync and interact with a Realm object in the way I'm used to.
Details at: Get Started with Realm Web & Atlas Device Sync (Preview)
I am just using the basic app scaffold created by Vite, and then importing Realm in App.vue. I am not (yet) using Realm anywhere else in the code.
import Realm, { App } from "realm";
As advised in the Realm SDK documentation, for the Web Assembly version I had to enable top-level await in vite.config.js:
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/
export default defineConfig({
plugins: [vue()],
esbuild: {
supported: {
'top-level-await': true
},
},
optimizeDeps: {
esbuildOptions: {
supported: {
"top-level-await": true
},
},
},
})
So this works without errors when I build and preview (vite build followed by vite preview).
However, when I do npm run dev (vite), the server starts as expected, but there are the following errors in the browser console:
[Error] wasm streaming compile failed: TypeError: Unexpected response MIME type. Expected 'application/wasm'
(anonymous function) (realm.js:726)
[Error] falling back to ArrayBuffer instantiation
(anonymous function) (realm.js:727)
[Error] failed to asynchronously prepare wasm: CompileError: WebAssembly.Module doesn't parse at byte 0: module doesn't start with '\0asm'
(anonymous function) (realm.js:717)
[Error] Aborted(CompileError: WebAssembly.Module doesn't parse at byte 0: module doesn't start with '\0asm')
abort (realm.js:661)
(anonymous function) (realm.js:718)
This doesn't happen if I build and preview, so I hope it won't actually be a problem, but I don't understand what is going on here and I'm curious about how to fix it for working during the development process.
Edit
Thanks to VonC for the answer. I tried using the custom middleware, but got errors that the file cannot be found.
The .wasm files are in node_modules/realm/dist, but it seems to be looking in node_modules/.vite instead.
This is the error if I use const wasmPath = path.join(__dirname, req.url); (i.e. without the public path component).
ENOENT: no such file or directory, open '<my_local_path>/vite-project/node_modules/.vite/deps/realm-js-wasm.wasm'
In the end I got it working by using the middleware solution and redirecting it to the Realm folder directly:
const wasmPath = path.join(__dirname, 'node_modules/realm/dist', path.basename(req.url));

The errors indicate a problem with the MIME type expected for WASM modules and the way the WebAssembly module is being loaded or parsed, as in this issue: the Vite development server is not correctly serving the
.wasmfile with theapplication/wasmMIME type.You can try and configure Vite to properly serve WASM files with the correct MIME type, modifying your
vite.config.jsfile to include custom middleware for handling.wasmfiles, as inmycelial/mycelial-jsissue 25:That custom middleware checks for requests ending in
.wasmand serves them with the correctContent-Typeheader. That assumes the.wasmfiles are located in apublicdirectory at the root of your project.And that would be tailored for development with Vite's dev server and assumes your production environment already correctly serves
.wasmfiles with the appropriate MIME type, as the issue does not manifest when usingvite buildfollowed byvite preview.True: instead of serving
.wasmfiles from a generic or incorrect path (like thepublicfolder or the.vitecache), directly point to the actual location of these files within thenode_modulesdirectory. Adjust the path in the middleware function: