上一篇文件: go 语言编译wasm 在浏览器端实现cbc模式加解密
为什么要使用 tinygo 安装及编译wasm? 上一篇文章写了使用 go 语言来编译 wasm, 但是编译出来文件有些大, 所以这次主要使用 tinygo 来编译, 可以编译出较小的 wasm 文件
先使用 brew 安装
brew tap tinygo-org/tools
brew install tinygo
tinygo version
如果安装失败, 可以直接下载代码包使用
安装方法:
https://tinygo.org/getting-started/install/macos/
注意: 安装成功后需要自己手动设置环境变量
设置成功后开始编译:
tinygo build -o main.wasm -target wasm ./main.go
报错:
error: could not find wasm-opt, set the WASMOPT environment variable to override
没有找到 wasm-opt
所以我们还需要安装
brew install binaryen
安装成功后继续编译: 报错
/usr/local/bin/wasm-opt: incompatible wasm-opt (need 102 or newer)
查看当前版本:
wasm-opt –version
wasm-opt version 101
版本太低了, 需要 102 以上
升级
brew 安装的版本太低, 手动编译:
https://github.com/WebAssembly/binaryen
这里需要注意:
这个仓库里面有个子仓库, 需要都 clone 下来才可以编译成功:
英文介绍如下:
Binaryen uses git submodules (at time of writing just for gtest), so before you build you will have to initialize the submodules:
git submodule init
git submodule update
After that you can build with CMake:
cmake . && make
下载编译
编译成功后, 把 bin 目录加入环境变量中,
重新打包:
GOOS=js GOARCH=wasm tinygo build -o static/main.wasm
打包出来的 wasm 只有 300kb
启动
报错: TypeError: WebAssembly.instantiate(): Import #0 module=”wasi_snapshot_preview1″ error: module is not
查找到原因:
要想在浏览器中跑 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
所以重新拷贝文件,
执行成功, 但是有报错:
syscall/js.finalizeRef not implemented
找到解决方案:
https://github.com/tinygo-org/tinygo/issues/1140
1 2 3 4 5 6 7 8 9 |
<script> const go = new Go(); go.importObject.env["syscall/js.finalizeRef"] = () => {}; WebAssembly.instantiateStreaming(fetch("main-tiny.wasm"), go.importObject) .then((result) => { const wasm = result.instance; go.run(wasm) }); </script> |
在 js 中加入
go.importObject.env[“syscall/js.finalizeRef”] = () => {};
刷新即可
Document
wasm_exec_tiny.js:268 Hello World 🌍
go__encrypt(‘666’)
‘6M8FT8UhkLpfqHHomzvbLg==’
关于 go的其他包加解密可参考: