经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Go语言 » 查看文章
golang语言中wasm 环境搭建的过程详解
来源:jb51  时间:2021/11/9 17:51:32  对本文有异议

golang 安装

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

  1. $ brew install golang
  2.  
  3. $ go version
  4. go version go1.17.2 darwin/arm64

golang 环境测试

新建文件 main.go ,写入:

  1. package main
  2.  
  3. import "fmt"
  4.  
  5. func main() {
  6. fmt.Println("Hello World!")
  7. }

执行 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 模块:

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

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

  1. $ brew tap tinygo-org/tools
  2. $ brew install tinygo
  3.  
  4. $ tinygo version
  5. 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

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

在浏览器中跑起来

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

  1. // 原生编译
  2. $ cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" .
  3.  
  4. // tinygo编译
  5. $ cp "$(tinygo env TINYGOROOT)/targets/wasm_exec.js" ./wasm_exec_tiny.js

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

  1. <!DOCTYPE html>
  2. <html lang="en">
  3. <head>
  4. <meta charset="UTF-8">
  5. <meta http-equiv="X-UA-Compatible" content="IE=edge">
  6. <meta name="viewport" content="width=device-width, initial-scale=1.0">
  7. <title>Document</title>
  8. <script src="./wasm_exec_tiny.js"></script>
  9. </head>
  10. <body>
  11. <script>
  12. const go = new Go(); // wasm_exec.js 中的定义
  13. WebAssembly.instantiateStreaming(fetch('./main-tiny.wasm'), go.importObject)
  14. .then(res => {
  15. go.run(res.instance); // 执行 go main 方法
  16. });
  17. </script>
  18. </body>
  19. </html>

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

  1. // python
  2. $ python3 -m http.server
  3. $ python2 -m SimpleHTTPServer
  4.  
  5. // node
  6. $ npm i -g http-server
  7. $ hs
  8.  
  9. // gp
  10. $ go get -u github.com/shurcooL/goexec
  11. $ 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 的初始化方式为:

  1. fetch('./main-tiny.wasm')
  2. .then(res => res.arrayBuffer())
  3. .then(buffer => {
  4. WebAssembly.instantiate(buffer, go.importObject)
  5. .then(res => {
  6. go.run(res.instance);
  7. })
  8. })

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

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号