使用Golang编译WebAssembly

WebAssembly 在前端的应用中得到了广泛的实践,来讲下使用 Golang 编译成 WebAssembly 的方法。

首先准备一份需要编译成 WebAssembly 的 Go 文件,例如:

package main
import "fmt"
var a = 4
func main() {
    fmt.Println(a)
}

在该文件的目录下直接使用 Go 自带的命令, 将 GO 文件编译成 wasm 。

GOOS=js GOARCH=wasm go build -o filename.wasm

然后在目录下可以看到一份以 .wasm 结尾的文件,这份文件就是编译出来我们需要在前端引入的 WebAssembly,因为 WebAssembly 与 JS 的通讯需要引入一个 50k-100k 的 JavaScript 类库作为基础设施,Go 本身提供了这个库。

cp "$GOROOT/misc/wasm/wasm_exec.js" /yourpath

然后就可以新建一份 html 文件来引入刚编译的 wasm 文件了,

<html>
  <head>
    <meta charset="utf-8">
    <script src="./wasm_exec.js"></script>
    <script>
      const go = new Go()
      WebAssembly.instantiateStreaming(fetch("filename.wasm"), go.importObject).
        then((result) => {
          go.run(result.instance)
        })
    </script>
  </head>
  <body></body>
</html>

当然如果你像我一样使用的是python 自带的 http server 服务的话还需要配置一下让 静态资源支持 wasm文件

sudo vim /usr/local/etc/mime.types

然后添加

application/wasm    wasm

这样在 Chrome 中就不会出现报错了,便能愉快的访问自己本地搭建的测试 wasm 的地址了。

最后作为一个 Go 吹,还是要指出 由于Go是一种垃圾收集语言,因此整个运行时都在wasm二进制文件中。因此,二进制文件通常有几MB的大小

比如像这个简单的几行 Go 代码编译出来的 wasm 文件就有 2.4M 大小。

相对于 C/C++ 这无疑是个巨大的缺点,另外 C/C++可以通过 Emscripten 编译成浏览器支持更广泛的 asm.js 。

希望以后 Golang 能对 wasm 的支持更棒吧。

发表评论

电子邮件地址不会被公开。 必填项已用*标注