如何在 create-react-app 中编译为 WASM?

blu*_*pee 5 go reactjs webpack webassembly

我想知道使用 webpack 编译 Go 到 WASM 的“规范方式”,以便在使用 CRA 创建的 React 应用程序中可用。

到目前为止,我已经尝试过以下方法:

  1. 使用 CRA 启动了一个新的 React 应用程序。

  2. yarn add --dev webpack-golang-wasm-async-loader通过(https://github.com/aaronpowell/webpack-golang-wasm-async-loader)安装了 webpack-golang-wasm-async-loader

  3. 通过安装react-app-rewired来yarn add --dev react-app-rewired编辑Webpack配置而不弹出

  4. config-overrides.js使用以下内容编辑该文件:

       const path = require('path');
    
       module.exports = function override(config, env) {
       const goExtensionRegExp = /\.go/;
    
       // add a dedicated loader for WASM
       config.module.rules.push({
           test: goExtensionRegExp,
           use: ['golang-wasm-async-loader']
       });
    
       config.node.fs = 'empty'
    
       return config;
     };
    
    Run Code Online (Sandbox Code Playgroud)

    按照加载程序自述文件中给出的配置说明:

      module.exports = {
        ...
        module: {
             rules: [
                 {
                     test: /\.go/,
                     use: ['golang-wasm-async-loader']
                 }
             ]
         },
         node: {
             fs: 'empty'
         }
    };
    
    Run Code Online (Sandbox Code Playgroud)
  5. 在我的App.js文件中,我有以下内容:

     import React from 'react';
    
     import wasm from './main.go'
    
     import logo from './logo.svg';
     import './App.css';
    
     class App extends React.Component {
    
       async init() {
         const result = await wasm.add(1, 2);
         console.log(result);
    
         const someValue = await wasm.someValue();
         console.log(someValue);
       }
    
       render() {
         return <div>Hello world</div>;
       }
     }
    
     export default App;
    
    Run Code Online (Sandbox Code Playgroud)
  6. 在我的main.go文件中,我有以下内容:

    package main
    
    import (
         "strconv"
         "syscall/js"
         "github.com/aaronpowell/webpack-golang-wasm-async-loader/gobridge"
     )
    
     func add(i []js.Value) (interface{},error) {
         ret := 0
    
         for _, item := range i {
             val, _ := strconv.Atoi(item.String())
             ret += val
         }
    
         return ret, nil
     }
    
     func main() {
         c := make(chan struct{}, 0)
    
         gobridge.RegisterCallback("add", add)
         gobridge.RegisterValue("someValue", "Hello World")
    
         <-c
     }
    
    Run Code Online (Sandbox Code Playgroud)

我的目录结构如下所示:

    |- root
       |- node_modules
       |- public
       |- src
          |- App.css
          |- App.js
          |- App.test.js
          |- index.css
          |- index.js
          |- logo.svg
          |- main.go
          |...
       |...
       |- config-overrides.js
       |- package.json
Run Code Online (Sandbox Code Playgroud)

运行后yarn start我收到以下错误:

./src/main.go Error: spawn undefined/bin/go ENOENT

我非常感谢任何有关如何使其发挥作用的帮助,并且我愿意使用另一种方法,这就是为什么我没有在标题中包含库名称。