Go1.17.2 发布暨 WebAssembly 入门教程
昨天凌晨,Go 官方发布了 Go1.17.2 和 1.16.9,这是两个小版本,重要修复一个安全问题。
从使用 GOARCH=wasm GOOS=js
构建的 WASM 模块调用函数时,传递非常大的参数可能会导致模块的一部分被参数中的数据覆盖。如果使用 wasmexec.js 执行 WASM 模块,则用户需要在重新构建任何模块后替换其副本。具体 issue 见:https://github.com/golang/go/issues/48797。
Go 语言中文网可以直接下载最新版本:https://studygolang.com/dl 。
我想,目前应该很少有人使用 Go 开发 WASM 吧,更多是在试验、学习。
借此,来一份简单的 Go WebAssembly 教程。
简介
什么是 WebAssembly?在其主页上:https://webassembly.org/ 有如下描述:
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 这两年挺火的,但生产使用还是很少。有兴趣可以学习了解。本文希望能够带给你一个初步印象。
推荐阅读