无聊玩玩WebAssembly,用Go语言写个应用

WebAssembly 是一种基于栈的虚拟机二进制指令格式,缩写为 WasmWasm 被设计成一种可移植的编译目标产出物,支持 Web 部署,客户端和服务端均可。

简言之,Wasm 是一种通用的虚拟机指令格式。任何平台只要实现了虚拟机,即可执行 Wasm 应用。工程师可以使用任何编程语言来发应用程序,只要最终能编译成 Wasm 即可。

因此,Wasm 是一个威力强大的中间层,让开发语言与执行平台完全解耦,可以任意组合。Wasm 可以跑在浏览器上,也可以直接跑在操作系统里面(比如 LinuxWindows )。硬件平台当然也不挑,ARMx86 都可以。

通用中间层通常会带来大量的性能损耗,为此 Wasm 在效率和安全性方面做了大量优化:

  • 高效快速

    Wasm 栈虚拟机指令编码成一种二进制格式,无论是尺寸还是加载时间都非常高效。它还利用各种平台都支持的硬件特性,试图取得接近原生的执行速度。

  • 安全

    Wasm 提供了一种内存安全,并且有沙盒隔离的执行环境,甚至可以在已有的 JavaScript 虚拟机中实现。而且它还强制实现浏览器的同源和权限安全策略。

  • 开放可调试

    Wasm 也提供可读的文本格式,在调试、测试、实验、调优、学习、教学和手写程序等场景非常有用。在 Web 应用中,支持以文本格式来查看 Wasm 模块的源码。

  • 开发Web平台组成部分

    Wasm 秉持 Web 无版本、特性测试以及向下兼容的特质。Wasm 模块既可以调用 JavaScript 上下文,也可以被 JavaScript 上下文调用。Wasm 可以使用浏览器提供能力,而且接口跟 JavaScript 一样。当然了,Wasm 也可以在非 Web 应用中嵌入。

用Go语言开发

Go 语言在 1.11 中实验性地加入对 WebAssembly 的支持,1.12 及后续版本又陆续做了优化,现已全面支持。

现在用 Go 语言来编写一个最简单的程序试试(程序命名为 main.go ):

1
2
3
4
5
6
7
8
9
package main

import (
	"fmt"
)

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

为了编译成 Wasm 二进制格式,我们需要加 GOOS=jsGOARCH=wasm 两个环境变量:

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

这个命令编译 main.go 这个程序,并生成 Wasm 可执行模块文件 main.wasm 。文件扩展名 .wasm 可以让 HTTP 服务器自动为其加上正确 Content-Type 头部,方便后续部署。

注意到,我们只能编译 main 包,否则会得到一个无法在 Wasm 中执行的对象文件。如果你想让一个已有包支持在 Wasm 中执行,可以将它转成 main 包再编译成二进制。

想要在浏览器中执行 main.wasm ,我们还需要一个 JavaScript 支持文件,以及一个 HTML 页面将所有部分连接到一起。其中,JavaScript 支持文件可以从 Go 工具中直接拷贝:

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

然后创建一个 index.html 文件并写上这些代码:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<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>
  • 4 行,引入 JavaScript 支持文件 wasm_exec.js ,这是我们刚刚从 Go 语言工具链中拷贝的;
  • 6~9 行,加载并执行 main.wasm

最后,将 index.htmlwasm_exec.jsmain.wasm 三个文件放在一起,并通过 Web 服务器部署好即可。如一起无误,在浏览器中访问 index.html 即可在 console 在到我们在 Go 语言中输出的内容。

如果您使用 VSCode 开发程序,推荐是用 Live Server 来部署 Web 应用,操作非常简单:右键点击 index.html ,再点击“用Live Server打开”即可。

订阅更新,获取更多学习资料,请关注我们的公众号:

【随笔】系列文章首发于公众号【小菜学编程】,敬请关注: