最后更新于

Golang生成WASM


WebAssembly(WASM)是一种可以在现代Web浏览器中运行的新型代码格式。Golang从1.11版本开始支持编译为WebAssembly,让我们可以在浏览器中运行Go代码。

🚀 Go代码示例

package main

import (
    "syscall/js"
)

// 加法函数
func add(this js.Value, inputs []js.Value) interface{} {
    a := inputs[0].Int()
    b := inputs[1].Int()
    return a + b
}

// 乘法函数
func mul(this js.Value, inputs []js.Value) interface{} {
    a := inputs[0].Int()
    b := inputs[1].Int()
    return a * b
}

func main() {
    c := make(chan struct{}, 0)

    // 注册函数到全局对象
    js.Global().Set("add", js.FuncOf(add))
    js.Global().Set("mul", js.FuncOf(mul))

    // 保持程序运行
    <-c
}

🔨 编译为WASM

系统要求

  • Go版本:1.11+(推荐1.18+)
  • 支持平台:Windows、Linux、macOS

编译命令

Windows:

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

Linux/macOS:

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

获取wasm_exec.js

# 复制Go运行时支持文件
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .

🌐 HTML集成

HTML文件

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Go WASM Demo</title>
    <meta http-equiv="Content-Security-Policy"
          content="script-src 'self' 'unsafe-inline' 'unsafe-eval'">
</head>
<body>
    <h1>Go WebAssembly Demo</h1>
    <button onclick="testFunctions()">测试函数</button>
    <div id="result"></div>

    <script src="wasm_exec.js"></script>
    <script src="index.js"></script>
</body>
</html>

JavaScript调用

const go = new Go();

WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject)
    .then((result) => {
        go.run(result.instance);
        console.log("WASM模块加载成功");
    })
    .catch((err) => {
        console.error("WASM加载失败:", err);
    });

// 测试函数
function testFunctions() {
    try {
        // 调用Go导出的函数
        const sum = add(10, 20);
        const product = mul(5, 6);

        document.getElementById('result').innerHTML = `
            <p>加法结果: 10 + 20 = ${sum}</p>
            <p>乘法结果: 5 × 6 = ${product}</p>
        `;

        console.log(`加法结果: ${sum}`);
        console.log(`乘法结果: ${product}`);
    } catch (error) {
        console.error("函数调用失败:", error);
    }
}

🚀 运行项目

启动本地服务器

由于浏览器安全限制,需要通过HTTP服务器访问:

# 使用Python启动简单服务器
python -m http.server 8080

# 或使用Go启动服务器
go run -m http.server 8080

# 或使用Node.js
npx http-server -p 8080

访问应用

打开浏览器访问:http://localhost:8080

📋 最佳实践

性能优化

  • 减小WASM文件大小:使用 -ldflags="-s -w" 编译选项
  • 异步加载:使用 WebAssembly.instantiateStreaming
  • 错误处理:添加完善的错误处理机制

调试技巧

# 编译时保留调试信息
GOOS=js GOARCH=wasm go build -o main.wasm main.go

# 查看WASM文件信息
wasm-objdump -h main.wasm

💡 提示:Go WASM适合计算密集型任务,但文件大小较大,需要权衡使用场景。