文章目录

    • 简介
    • 入门示例
    • 总结

简介

什么是 WebAssembly?在其主页上:https://webassembly/ 有如下描述:

WebAssembly(缩写为 Wasm)是一种用于基于堆栈的虚拟机的二进制指令格式。Wasm 被设计为用于编译编程语言的可移植目标,支持在 Web 上部署客户端和服务器应用程序。

目前 Rust 对 WebAssembly 的支持较好。那 Go 什么时候开始支持支持 WebAssembly 的呢?

Go 1.11 向 WebAssembly 添加了一个实验性端口。Go 1.12 对其某些部分进行了改进,Go 1.13 有了进一步改进。

入门示例

首先,请保证安装了 Go1.11 以上版本,建议安装最新版本 Go。

在本地创建一个项目:gowasm(Windows 用户自行修改路径)

$ mkdir ~/gowasm
$ cd ~/gowasm
$ go mod init gowasm
$ touch main.go

要为 Web 编译基本的 Go 包,打开 main.go,填上如下代码:

package main

import "fmt"

func main() {
 fmt.Println("Hello, WebAssembly!")
}

为 WebAssembly 编译设置GOOS=js和GOARCH=wasm环境变量:

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

这将构建包并生成一个名为 main.wasm 的可执行 WebAssembly 模块文件。.wasm 文件扩展名使得通过 HTTP 用正确的 Content-Type 标头来更好地提供它。

请注意,你只能编译 main 包。否则,你将获得一个无法在 WebAssembly 中运行的目标文件。如果你有一个包希望能够与 WebAssembly 一起使用,请将其转换为 main 包并构建它得到一个二进制文件。

要在浏览器中执行 main.wasm,我们还需要一个 JavaScript 支持文件和一个 HTML 页面来将所有内容连接在一起。

复制 JavaScript 支持文件:

$ cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .

创建一个index.html文件:

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

如果你的浏览器尚不支持WebAssembly.instantiateStreaming,可以使用 polyfill。

然后从 Web 服务器服务这三个文件(index.html、wasm_exec.js和 main.wasm)。例如,使用 goexec。注意,安装 goexec 后,放入 PATH 目录,方便使用:

# 先安装 goexec
$ go install github.com/shurcooL/goexec@latest
# 执行 goexec(如果提示你缺少 github.com/shurcooL/go-goon,请 go get 下载)
$ goexec 'http.ListenAndServe(`:8080`, http.FileServer(http.Dir(`.`)))'

当然也可以使用任何其他的方式提供 HTTP 服务。

打开浏览器访问 http://localhost:8080/index.html,打开 JavaScript 调试控制台(Console Tab),你应该会看到输出:Hello, WebAssembly!

你可以修改程序、重新编译 main.wasm,刷新以查看新输出。(goexec 不需要重启)

总结

Go 的安全更新,如果涉及到你的项目,建议升级,否则可以不升级。WebAssembly 这两年挺火的,但生产使用还是很少。有兴趣可以学习了解。本文希望能够带给你一个初步印象。

更多推荐

WebAssembly 入门教程