golang 装置

brew
$ brew install golang

$ go version
go version go1.17.2 darwin/arm64

golang 环境测试

main.go
package main

import "fmt"

func main() {
  fmt.Println("Hello World!")
}
go run main.go
$ go run main.go
Hello World!
GO MODULESgo mode initGO111MODULE=auto

将 golang 打包为 WASM

tinygotinygo
// macos
$ GOOS=js GOARCH=wasm go build -o main.wasm

// windows 长期设置 golang 环境参数(仅作用于以后CMD)
$ set GOOS=js 
$ set GOARCH=wasm
$ go build -o main.wasm
$ brew tap tinygo-org/tools
$ brew install tinygo

$ tinygo version
tinygo version 0.20.0 darwin/amd64 (using go version go1.17.2 and LLVM version 11.0.0)
$ tinygo build -o main-tiny.wasm
$ du -sh ./*.wasm
228K    ./main-tiny.wasm
1.9M    ./main.wasm

在浏览器中跑起来

main.wasmtinygo
// 原生编译
$ cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .

// tinygo编译
$ cp "$(tinygo env TINYGOROOT)/targets/wasm_exec.js" ./wasm_exec_tiny.js
HTMLindex.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./wasm_exec_tiny.js"></script>
</head>
<body>
  <script>
    const go = new Go(); // wasm_exec.js 中的定义
    WebAssembly.instantiateStreaming(fetch('./main-tiny.wasm'), go.importObject)
      .then(res => {
        go.run(res.instance); // 执行 go main 办法
      });
  </script>
</body>
</html>

最初,起一个 http server 让它跑起来吧~

// python
$ python3 -m http.server
$ python2 -m SimpleHTTPServer

// node
$ npm i -g http-server
$ hs

// gp
$ go get -u github.com/shurcooL/goexec
$ goexec 'http.ListenAndServe(`:8080`, http.FileServer(http.Dir(`.`)))'

异样记录

> TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.
fetch('./main-tiny.wasm')
  .then(res => res.arrayBuffer())
  .then(buffer => {
    WebAssembly.instantiate(buffer, go.importObject)
      .then(res => {
        go.run(res.instance);
      })
  })