【问题标题】:How to use WebAssembly (wasm) with create-react-app如何将 WebAssembly (wasm) 与 create-react-app 一起使用
【发布时间】:2020-04-06 17:47:40
【问题描述】:

我使用create-react-app 和带有wasm 的库,它被称为sax-wasm。 稍微修改一下网页的示例代码我得到了这个:

import { SaxEventType, SAXParser } from 'sax-wasm';

async function loadAndPrepareWasm() {
  const saxWasmResponse = await import('sax-wasm/lib/sax-wasm.wasm');
  const saxWasmbuffer = await saxWasmResponse.arrayBuffer();
  const parser = new SAXParser(SaxEventType.Attribute | SaxEventType.OpenTag, {
    highWaterMark: 64 * 1024,
  });

  const ready = await parser.prepareWasm(new Uint8Array(saxWasmbuffer));
  if (ready) {
    return parser;
  }
}

loadAndPrepareWasm().then(console.log);

当我运行yarn start 命令时,我的构建失败了:

Failed to compile.

./node_modules/sax-wasm/lib/sax-wasm.wasm
Module parse failed: magic header not detected
File was processed with these loaders:
 * ./node_modules/file-loader/dist/cjs.js
You may need an additional loader to handle the result of these loaders.
Error: magic header not detected

【问题讨论】:

标签: webpack create-react-app webassembly


【解决方案1】:

您最终希望在浏览器中使用 wasm。这意味着您必须在浏览器中访问它。

我安装了esbuild-wasm。有两种设置方法:

1- 在节点模块中找到模块“node_modules/esbuild-wasm”,您将看到一个文件“esbuild-wasm”并将其放在公用文件夹中。这已经编译好的代码可以直接在浏览器内部工作。内部组件:

import * as esbuild from "esbuild-wasm"
import {useRef, useState} from "react"

// you can use ref to keep a reference to any Js value inside of a component. 
const ref=useRef()
const startEsbuildService=async()=>{
   // this object is responsible for transpiling
   ref.current=await esbuild.startService({
   worker:true,
   // we are pointing to the public directory
   wasmURL:'/esbuild.wasm'})
}

第二种方式:

const startEsbuildService = async () => {
    ref.current = await esbuild.startService({
      worker: true,
      // unpkg.com provides all npm modules without CORS error
      wasmURL: "https://unpkg.com/esbuild-wasm@0.8.42/esbuild.wasm",
    });
  };

这就是你使用它的方式

 // you store the code
    const [codeInput,setCodeInput]=useState("")
    const [transpiledCode,setTranspiledCode]=useState("")
const onClick= async ()=>{
   if(!ref.current) return;
   const transformedCode=await ref.current.transform(codeInput,{
      // es-build can handle different types of code
      loader:'jsx',
      target: 'es2015'})
   // this will rerender our component
   setTranspiledCode(transformedCode)
}

【讨论】:

    【解决方案2】:

    以下解决方案适用于 CRA 3.x。对于 CRA 4.x,您应该使用 craco

    CRA 不支持 WASM。但是你可以解决它。您需要覆盖 webpack 配置。有多个软件包可以做到这一点。我用react-app-rewired。你需要 wasm-loader 包

    比添加你的覆盖config-overrides.js

    const path = require('path');
    
    module.exports = function override(config, env) {
    
        /**
         * Add WASM support
         */
    
        // Make file-loader ignore WASM files
        const wasmExtensionRegExp = /\.wasm$/;
        config.resolve.extensions.push('.wasm');
        config.module.rules.forEach(rule => {
            (rule.oneOf || []).forEach(oneOf => {
                if (oneOf.loader && oneOf.loader.indexOf('file-loader') >= 0) {
                    oneOf.exclude.push(wasmExtensionRegExp);
                }
            });
        });
    
        // Add a dedicated loader for WASM
        config.module.rules.push({
            test: wasmExtensionRegExp,
            include: path.resolve(__dirname, 'src'),
            use: [{ loader: require.resolve('wasm-loader'), options: {} }]
        });
    
        return config;
    };
    

    package.json 我是这样做的:

    {
    ...
      "scripts": {
        "start": "react-app-rewired start",
        "build": "react-app-rewired build",
        "test": "react-app-rewired test",
        "eject": "react-scripts eject",
        "predeploy": "npm run build",
        "deploy": "gh-pages -d build"
      },
    ...
      "devDependencies": {
        "react-app-rewired": "2.1.3",
        "wasm-loader": "1.3.0"
      }
    }
    

    【讨论】:

    • 非常感谢!对我来说,解决方案是这个的一半。我只需要让文件加载器忽略 .wasm 文件。当我为 WASM 添加专用加载器时,它不起作用。此外,为 .wasm 文件设置 "type": "javascript/auto" 对我也不起作用。 (我正在使用 wasm-bindgen)
    • 注意:为了能够加载wasm文件,你的网络服务器需要支持wasm,返回wasm mime类型为application/wasm
    猜你喜欢
    • 1970-01-01
    • 2020-05-09
    • 2019-05-31
    • 1970-01-01
    • 2019-01-30
    • 1970-01-01
    • 2020-05-14
    • 2017-10-26
    • 2021-01-30
    相关资源
    最近更新 更多