使用 Realm Web SDK 的 Vite + Vue 应用程序中的 Web Assembly (WASM) 错误

问题描述 投票:0回答:1

我正在使用 MongoDB Realm / App Services 为现有 iOS 应用程序制作 Web 前端。

标准 Realm Web SDK 仅允许身份验证和后端功能,因此我尝试使用 Web Assembly 版本的预览版 (

[email protected]
),以便我可以使用设备同步并以我的方式与 Realm 对象交互我习惯了。

详细信息位于:Realm Web 和 Atlas 设备同步入门(预览版)

我只是使用Vite创建的基础应用脚手架,然后在

App.vue
中导入Realm。我(还)没有在代码中的其他地方使用 Realm。

import Realm, { App } from "realm";

根据 Realm SDK 文档中的建议,对于 Web Assembly 版本,我必须在

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
      },
    },
  },
})

因此,当我构建和预览时,这可以正常工作(

vite build
,然后是
vite preview
)。

但是,当我执行

npm run dev
vite
)时,服务器按预期启动,但浏览器控制台中出现以下错误:

[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)

如果我构建和预览,这种情况不会发生,所以我希望这实际上不会成为问题,但我不明白这里发生了什么,我很好奇如何修复它以便在开发过程中工作过程。

javascript mongodb vue.js realm vite
1个回答
0
投票

这些错误表明 WASM 模块所需的 MIME 类型以及加载或解析 WebAssembly 模块的方式存在问题,如 此问题所示:Vite 开发服务器未正确提供带有

.wasm
application/wasm
 文件
MIME 类型。

您可以尝试配置 Vite 以使用正确的 MIME 类型正确提供 WASM 文件,修改您的

vite.config.js
文件以包含用于处理
.wasm
文件的自定义中间件,如
mycelial/mycelial-js
问题 25
:

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import fs from 'fs'
import path from 'path'

// Custom middleware to serve wasm files with the correct MIME type
const wasmMiddleware = () => {
  return {
    name: 'wasm-middleware',
    configureServer(server) {
      server.middlewares.use((req, res, next) => {
        if (req.url.endsWith('.wasm')) {
          const wasmPath = path.join(__dirname, 'public', req.url);
          const wasmFile = fs.readFileSync(wasmPath);
          res.setHeader('Content-Type', 'application/wasm');
          res.end(wasmFile);
          return;
        }
        next();
      });
    },
  };
};

export default defineConfig({
  plugins: [vue(), wasmMiddleware()],
  esbuild: {
    supported: {
      'top-level-await': true
    },
  },
  optimizeDeps: {
    esbuildOptions: {
      supported: {
        "top-level-await": true
      },
    },
  },
})

该自定义中间件检查以

.wasm
结尾的请求,并为它们提供正确的
Content-Type
标头。假设
.wasm
文件位于项目根目录的
public
目录中。
这将是为使用 Vite 的开发服务器进行开发而定制的,并假设您的生产环境已经正确地提供了具有适当 MIME 类型的
.wasm
文件,因为在使用
vite build
后跟
vite preview
时,问题不会显现出来。

© www.soinside.com 2019 - 2024. All rights reserved.