使用 WebAssembly 和 Go:从入门到精通——完整指南

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

WebAssembly 和 Go 简介



WebAssembly (WASM) 是一种低级二进制格式,允许在浏览器中直接运行用 JavaScript 以外的语言编写的代码。Go (Golang) 凭借其强大的标准库和出色的并发支持,已成为编译为 WASM 的最佳候选语言之一。在本文中,我们将详细讲解从工具安装到部署完整解决方案的 Go WebAssembly 开发流程。



现代 Web 应用程序需要高性能,而 WebAssembly 提供了以接近原生速度运行 Go 代码的能力。这为将繁重计算、游戏引擎和数据处理系统直接移植到浏览器中打开了大门。



环境安装与配置



开始之前,请确保您已安装最新版本的 Go (1.21+)。使用 WebAssembly 需要 tinygo 编译器(可选,用于减小二进制文件大小)或标准的 go build。



基本要求

  • Go 1.21 或更高版本
  • 支持 WebAssembly 的浏览器(Chrome、Firefox、Safari、Edge)
  • 基本的 JavaScript 理解


设置环境变量

# 设置 GOOS 和 GOARCH 以进行交叉编译export GOOS=jsexport GOARCH=wasm

# 检查配置是否正确go env GOOS GOARCH# 应显示:js wasm


还需要从 Go 标准库复制支持文件 wasm_exec.js:

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


编写并编译第一个 WASM 模块



让我们创建一个简单的模块,该模块将导出一个用于两个数相加的函数,并在浏览器控制台中输出一条消息。



Go 代码

package main

import "syscall/js"

func add(this js.Value, args []js.Value) interface{} { if len(args) < 2 { return "Error: need two arguments" } a := args[0].Int() b := args[1].Int() return a + b}

func main() { // 在全局对象中注册函数 js.Global().Set("goAdd", js.FuncOf(add)) // 阻塞 goroutine 以防止 WASM 退出 select {}}


编译为 WASM

go build -o main.wasm main.go


编译后,您将得到一个大小约为 2-3 MB 的 main.wasm 文件(使用标准编译器)。对于生产环境,建议使用 TinyGo,它可以将大小减小到 10-50 KB。



与 JavaScript 和 HTML 集成



现在创建一个 HTML 页面来加载和使用我们的 WASM 模块。



HTML 模板

<!DOCTYPE html><html><head>    <meta charset="utf-8">    <title>Go WebAssembly 演示</title></head><body>    <h1>Go + WebAssembly</h1>    <input type="number" id="num1" value="10">    <input type="number" id="num2" value="20">    <button onclick="calculate()">相加</button>    <p>结果:<span id="result">0</span></p>

<script src="wasm_exec.js"></script> <script> const go = new Go(); WebAssembly.instantiateStreaming( fetch("main.wasm"), go.importObject ).then((result) => { go.run(result.instance); console.log("WASM 已加载!"); });

function calculate() { const a = parseInt(document.getElementById('num1').value); const b = parseInt(document.getElementById('num2').value); const result = goAdd(a, b); document.getElementById('result').textContent = result; } </script></body></html>


内存与复杂

博客

书籍推荐