golang语言中wasm 环境搭建的过程详解

 更新时间:2021年11月09日 16:46:54   作者:shushushu  
将 golang 打包为 WASM,通常有两种打包方式,一种是 golang 自带的,另外是使用 tinygo ,接下来通过本文给大家介绍golang语言中wasm 环境搭建的过程,感兴趣的朋友一起看看吧

golang 安装

通过官方地址 下载。MacOS 也可通过 brew 快速安装:

$ brew install golang

$ go version
go version go1.17.2 darwin/arm64

golang 环境测试

新建文件 main.go ,写入:

package main

import "fmt"

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

执行 go run main.go ,将输出:

$ go run main.go
Hello World!

如果启用了 GO MODULES ,则需要使用 go mode init 初始化模块,或设置 GO111MODULE=auto 。

将 golang 打包为 WASM

通常有两种打包方式,一种是 golang 自带的,另外是使用 tinygo 。推荐使用 tinygo ,因为编译出的 wasm 模块更小。

  • 使用 golang 原生编译

在编译 wasm 模块前,需要设置 golang 交叉编译参数,目标系统 GOOS=js 和目标架构 GOARCH=wasm ,编译 wasm 模块:

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

// windows 临时设置 golang 环境参数(仅作用于当前CMD)
$ set GOOS=js 
$ set GOARCH=wasm
$ go build -o main.wasm
  • 使用 tinygo 编译

直接按照官方文档安装即可,MacOS 如下:

$ brew tap tinygo-org/tools
$ brew install tinygo

$ tinygo version
tinygo version 0.20.0 darwin/amd64 (using go version go1.17.2 and LLVM version 11.0.0)

使用以下命令对 main.go 再次进行打包:

$ tinygo build -o main-tiny.wasm

  • 打包文件大小对比
$ du -sh ./*.wasm
228K    ./main-tiny.wasm
1.9M    ./main.wasm

在浏览器中跑起来

要想在浏览器中跑 main.wasm ,首先需要 JS 胶水代码,golang 已经为我们提供了,直接复制过来。需要注意的是,使用 tinygo 和 原生编译的胶水代码是有差异的,根据具体情况拷贝对应的:

// 原生编译
$ cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .

// tinygo编译
$ cp "$(tinygo env TINYGOROOT)/targets/wasm_exec.js" ./wasm_exec_tiny.js

其次,需要一个 HTML 入口文件,创建 index.html 文件,并写入以下代码:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
  <script src="./wasm_exec_tiny.js"></script>
</head>
<body>
  <script>
    const go = new Go(); // wasm_exec.js 中的定义
    WebAssembly.instantiateStreaming(fetch('./main-tiny.wasm'), go.importObject)
      .then(res => {
        go.run(res.instance); // 执行 go main 方法
      });
  </script>
</body>
</html>

最后,起一个 http server 让它跑起来吧~

// python
$ python3 -m http.server
$ python2 -m SimpleHTTPServer

// node
$ npm i -g http-server
$ hs

// gp
$ go get -u github.com/shurcooL/goexec
$ goexec 'http.ListenAndServe(`:8080`, http.FileServer(http.Dir(`.`)))'

异常记录

  • 通过 node 的 http-server 起的服务,加载会报错:

> TypeError: Failed to execute 'compile' on 'WebAssembly': Incorrect response MIME type. Expected 'application/wasm'.

原因是 wasm 文件响应头的 content-type 为 application/wasm; charset=utf-8 ,应该为 application/wasm 。已知的解决方法为修改 HTML 中 wasm 的初始化方式为:

fetch('./main-tiny.wasm')
  .then(res => res.arrayBuffer())
  .then(buffer => {
    WebAssembly.instantiate(buffer, go.importObject)
      .then(res => {
        go.run(res.instance);
      })
  })

到此这篇关于golang语言中wasm 环境搭建的文章就介绍到这了,更多相关golang wasm 环境搭建内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • go语言限制协程并发数的方案详情

    go语言限制协程并发数的方案详情

    一个线程中可以有任意多个协程,但某一时刻只能有一个协程在运行,多个协程分享该线程分配到的计算机资源,接下来通过本文给大家介绍go语言限制协程的并发数的方案详情,感兴趣的朋友一起看看吧
    2022-01-01
  • golang package time的用法具体详解

    golang package time的用法具体详解

    本篇文章主要介绍了golang package time的用法具体详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-05-05
  • 源码剖析Golang如何fork一个进程

    源码剖析Golang如何fork一个进程

    创建一个新进程分为两个步骤,一个是fork系统调用,一个是execve 系统调用,本文将从源码的角度带大家剖析一下Golang是如何fork一个进程的
    2023-06-06
  • 6行代码快速解决golang TCP粘包问题

    6行代码快速解决golang TCP粘包问题

    在用golang开发人工客服系统的时候碰到了粘包问题,那么什么是粘包呢?下面这篇文章主要给大家介绍了关于如何通过6行代码快速解决golang TCP粘包问题的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考借鉴下面随着小编来一起学习学习吧。
    2018-03-03
  • golang语言中for循环语句用法实例

    golang语言中for循环语句用法实例

    这篇文章主要介绍了golang语言中for循环语句用法,实例分析了for循环遍历的使用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-01-01
  • 深入解析golang中的标准库flag

    深入解析golang中的标准库flag

    Go语言内置的flag包实现了命令行参数的解析,flag包使得开发命令行工具更为简单,下面通过本文给大家详细介绍下golang中的标准库flag相关知识,感兴趣的朋友一起看看吧
    2021-11-11
  • go-cqhttp智能聊天功能的实现

    go-cqhttp智能聊天功能的实现

    这篇文章主要介绍了go-cqhttp智能聊天功能,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • 详解golang consul-grpc 服务注册与发现

    详解golang consul-grpc 服务注册与发现

    这篇文章主要介绍了详解golang consul-grpc 服务注册与发现,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06
  • Go语言开发快速学习CGO编程

    Go语言开发快速学习CGO编程

    这篇文章主要为大家介绍了Go语言开发之快速学习CGO编程,看了本文你就会发现CGO编程其实没有想象的那么难,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-04-04
  • 创建第一个Go语言程序Hello,Go!

    创建第一个Go语言程序Hello,Go!

    这篇文章主要介绍了创建第一个Go语言程序Hello,Go!本文详细的给出项目创建、代码编写的过程,同时讲解了GOPATH、Go install等内容,需要的朋友可以参考下
    2014-10-10

最新评论