如何满足 wasm 的严格 mime 类型检查?

Jos*_*ore 9 browser webpack server webassembly

我得到了一个使用 emscripten 编译的 webassembly 模块。现在我正在尝试使用 expressjs 在网页中提供它。

我已经尝试按照这个要点来通过 webpack 包含 webassembly,包括我发现的一个修改,因为这个要点有点旧。

webpack 看起来像这样:

const path = require('path');

module.exports = {
  optimization: {
    mangleWasmImports: false
  },
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, './dist/'),
    filename: 'dynamic-graph.bundle.js'
  },
  target: "web",
  module: {
    rules: [
      // Emscripten JS files define a global. With `exports-loader` we can 
      // load these files correctly (provided the global’s name is the same
      // as the file name).
      {
        test: /fourd\.js$/,
        loader: "exports-loader"
      },
      // wasm files should not be processed but just be emitted and we want
      // to have their public URL.
      {
        test: /fourd\.wasm$/,
        type: "javascript/auto",
        loader: "file-loader",
        options: {
          publicPath: "dist/"
        }
      }
    ]
  }
}

Run Code Online (Sandbox Code Playgroud)

我在开发服务器上设置了 https,因为我知道这有时会导致问题。这是一个自签名证书,但 Chrome 和 Firefox 让我解决了这个问题。

const path = require('path');

module.exports = {
  optimization: {
    mangleWasmImports: false
  },
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, './dist/'),
    filename: 'dynamic-graph.bundle.js'
  },
  target: "web",
  module: {
    rules: [
      // Emscripten JS files define a global. With `exports-loader` we can 
      // load these files correctly (provided the global’s name is the same
      // as the file name).
      {
        test: /fourd\.js$/,
        loader: "exports-loader"
      },
      // wasm files should not be processed but just be emitted and we want
      // to have their public URL.
      {
        test: /fourd\.wasm$/,
        type: "javascript/auto",
        loader: "file-loader",
        options: {
          publicPath: "dist/"
        }
      }
    ]
  }
}

Run Code Online (Sandbox Code Playgroud)

在之前的版本中,我可以使用 Module.onRuntimeInitialized 来等待 wasm 模块被实例化。该代码仍然有效,我使用与以前相同的 em++ 标志编译了 webpack,即-std=c++11 -s WASM=1 -s ALLOW_MEMORY_GROWTH=1 -s SAFE_HEAP=1 -O0 -g4 -s ASSERTIONS=1

我在浏览器中得到的错误如下:Failed to load module script: The server responded with a non-JavaScript MIME type of "application/wasm". Strict MIME type checking is enforced for module scripts per HTML spec.这让我陷入循环,因为我认为 application/wasm 正是 MIME 类型应该是什么。

loo*_*ops 0

application/wasm确实是用于 WASM 文件的正确 MIME 类型。问题在于 WASM 没有通过正确的方式导入WebAssembly.instantiate[Streaming]。相反,它是通过以下方式导入的:

import { add } from "./add.wasm";
Run Code Online (Sandbox Code Playgroud)

通常,这会被转换为WebAssembly.instantiate调用,但这种情况并没有发生。相反,该模块是在没有import将 s 转译为正确导入的情况下提供服务的。确保您正在转译 JavaScript,而不仅仅是将其作为静态文件提供,就像该代码中的情况一样。或者,您也可以WebAssembly.instantiate自己拨打电话。