如何在使用 create-react-app 创建的文件中导入 Emscripten 生成的 .wasm/js 文件

How can I import Emscripten generated .wasm/js files in files created with create-react-app

我有一个库,我可以使用 Emscripten 生成的 .html 文件成功构建 & 运行。我现在想将它与 React 一起使用,但是,我收到一个我无法修复的 MIME 类型错误。以下是我生成 React 应用程序和 .wasm 文件所采取的步骤

npx create-react-app Whosebug

DEST=Whosebug/src/Whosebug.html

sudo docker run --rm -v $(pwd):/src trzeci/emscripten emmake make

$ docker run --rm -v $(pwd):/src trzeci/emscripten emcc \
    ... o. files
    -s MODULARIZE=1 \
    -s ERROR_ON_UNDEFINED_SYMBOLS=0 \
    -s EXPORT_NAME=Whosebug \
    -o ${DEST}

# disable eslint for the generate file
sed -i '1s;^;/* eslint-disable */\n;' ${DEST}

我希望能够在 Whosebug.js

中导入 Whosebug 对象
App.js
...

import Whosebug from './Whosebug';
console.log(Whosebug());

...

但是开发服务器加载失败,控制台显示这些警告。

m streaming compile failed: TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.
(anonymous) @ Whosebug.js:1667
Promise.then (async)
createWasm @ Whosebug.js:1663
Module.asm @ Whosebug.js:1694
(anonymous) @ Whosebug.js:5322
./src/App.js @ App.js:5
__webpack_require__ @ bootstrap:781
fn @ bootstrap:149
./src/index.js @ index.css?f3f6:45
__webpack_require__ @ bootstrap:781
fn @ bootstrap:149
0 @ Whosebug.js:5867
__webpack_require__ @ bootstrap:781
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1
Whosebug.js:1668 falling back to ArrayBuffer instantiation
(anonymous) @ Whosebug.js:1668
Promise.then (async)
createWasm @ Whosebug.js:1663
Module.asm @ Whosebug.js:1694
(anonymous) @ Whosebug.js:5322
./src/App.js @ App.js:5
__webpack_require__ @ bootstrap:781
fn @ bootstrap:149
./src/index.js @ index.css?f3f6:45
__webpack_require__ @ bootstrap:781
fn @ bootstrap:149
0 @ Whosebug.js:5867
__webpack_require__ @ bootstrap:781
checkDeferredModules @ bootstrap:45
webpackJsonpCallback @ bootstrap:32
(anonymous) @ main.chunk.js:1
Whosebug.js:1654 failed to asynchronously prepare wasm: CompileError: AsyncCompile: Wasm decoding failed: expected magic word 00 61 73 6d, found 3c 21 44 4f @+0

第一个报错说MIME类型错误, question tells me to update node-mime and webpack-dev-server. node-mime isn't present in my node_modules, but webpack-dev-server is and this问题,显然解决了我的问题,在3.3.1上可用。

$ npm run eject

然后我将 webpack-dev-server 版本更改为 3.3.1 并安装。

现在我 运行 npm run start 并单步执行代码,我可以确认我到达了正确的开发服务器。

但我的错误仍然存​​在。我觉得我在这里遗漏了一些明显的东西。

我必须做几件事才能让它工作,我在这里的大部分故障排除都是徒劳的(开发服务器根本不提供 .wasm 文件,它依赖于 .html 当它找不到你想要的东西时,这就是我的 MIME 错误的来源)。

如何制作 EMSCRIPTEN JAVASCRIPT 使用 create-react-app

  1. emcc 的 .wasm 输出复制到 react-app/public 文件夹 cp Whosebug.wasm gifsicle-react/public/Whosebug.wasm
  2. eslint-disable 添加到文件的顶部(我使用这个 sed 命令)sed -i.old '1s;^;\/* eslint-disable *\/;' Whosebug.js
  3. 将.js中.wasm文件的相对路径替换为绝对路径。 (这是获取 /public 目录中的文件所必需的)sed -i.old "s|Whosebug.wasm|/Whosebug.wasm|" Whosebug.js
  4. 生成的javascript会尝试解析相对于网站目录的路径。注释掉这一行 sed -i.old "s|wasmBinaryFile = locateFile|// wasmBinaryFile = locateFile|" Whosebug.js

我最后写了 this 博客 post,其中详细介绍了我是如何做到这一点的。