把一个 Go 工具编译到 wasm
时间: 2020-08-27来源:V2EX
前景提要
起因
前段时间写了个 API 文档生成工具 mkdoc ,因为并没有像 swag-go 一样依赖 go CLI 后来就在想能不能把他编译到 wasm 然后放到网页上,这样就能方便大家 0 部署就能对他有个了解。
成果
👉 在线体验 👈 ( : 如果你对 mkdoc 感兴趣,欢迎 fork&star
一些问题 工具里用到了文件系统,go 提供的 wasm_exec.js 中没有实现文件系统 用到了 os.Getwd 系统调用,syscall/js 没有直接支持 一些 go 和 js 之间的交互问题
解决
文件系统
在 wasm_exec.js 中可以看到一个未实现的 node fs API ,那我们只要在浏览器中按照 node fs API 实现一个 memory filesystem ,就能解决文件系统的问题。
但是自己去造轮子太麻烦,找来找去找到了 memfs 这个库(给作者点 100 个👍)。有了 memfs,我按照他的的使用方式把他提供的 fs 赋值到 window.fs 上,go 就会用这个 fs 了。
系统调用
看先 os.Getwd 的源码 // Getwd returns a rooted path name corresponding to the // current directory. If the current directory can be // reached via multiple paths (due to symbolic links), // Getwd may return any one of them. func Getwd() (dir string, err error) { if runtime.GOOS == "windows" || runtime.GOOS == "plan9" { return syscall.Getwd() } // Clumsy but widespread kludge: // if $PWD is set and matches ".", use it. dot, err := statNolog(".") if err != nil { return "", err } dir = Getenv("PWD") if len(dir) > 0 && dir[0] == '/' { d, err := statNolog(dir) if err == nil && SameFile(dot, d) { return dir, nil } }
发现他会检查 PWD 环境变量,如果发现当前就是 $PWD 则会直接使用$PWD 的值, 所以在启动的时候加一句 set env 就能 getwd 的目录不正确的问题了。 func initJS() { //... os.Setenv("PWD", "/") }
交互
这里主要写一个把 go 的 log.Println 绑定到 js console.log 的方法,其他看文档就可以了。 func (c *ConsoleWriter) Write(p []byte) (n int, err error) { js.Global().Get("console").Call("log", string(p)) return len(p), nil } func (c *ConsoleWriter) Log(s string) { c.Write([]byte(s)) } var console = new(ConsoleWriter) func initJS() { log.SetOutput(console) // ... }

科技资讯:

科技学院:

科技百科:

科技书籍:

网站大全:

软件大全:

热门排行