如何在JavaScript中使用Golang库?
如何在JavaScript中使用Golang库? 大家好!
我正在我的项目中使用一个Go开源库。
我们的整个项目都是用JS编写的,所以我希望能在某些JS代码中使用整个Go库。
有没有人知道并推荐一些在JS中或与JS一起使用Go的合适(高效)方法?
提前感谢,
Hoodie
这是一篇非常有用的文章。感谢分享!
更多关于如何在JavaScript中使用Golang库?的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你好 Sibert,
我希望能够更深入地使用 Go 库,例如在 JS 中使用它的函数或文件本身。
不过无论如何,还是谢谢你!
你好,安迪
我想在同一台Mac机器上使用NodeJS来运行一个Go库。 所以我正在尝试检查GopherJS和这个Go库的兼容性!
例如,在JS中使用其函数或文件本身
我也在寻找将Go与Javascript结合使用的方法。但我发现,除了某种微服务之外,没有其他方法可以在解释型语言和编译型语言之间进行通信(它们不使用相同的引擎)。也就是说来回发送消息。如果能证明我是错的,我会很高兴。
引用 hoodie: 有没有一种合适(高效)的方式在 JavaScript 中使用 Go 或与 JavaScript 一起使用?
一种方法是使用 JavaScript 的 fetch() 与具有端点的 Go HTTP 服务器进行通信。
以下代码通过使用 innerHTML 将期望的 Go 输出写入网页:
function ask_go() {
let url = "/askgo"
fetch(url)
.then((res) => res.text())
.then((response) => {
document.getElementById("content").innerHTML = response;
})
.catch((error) => alert("Error:", error));
}
正如你所说,我也发现了那些选项,以及将Go包编译成C共享库的方法(从其他语言调用Go函数 | 作者:Vladimir Vivien | Learning the Go Programming Language | Medium)!
因此,如果不存在其他更好的选择,那么深入研究其中一种(或几种)方法会更好!
谢谢大家!
你是否已经研究过:
- GopherJS(即将Go编译为JS),或者
- 将Go编译为WASM?
在没有深入研究这些选项的情况下,我认为这些可能是从JS调用Go库的合适方法。
编辑补充:
GopherJS 允许从JS调用Go代码。
WebAssembly 允许从JavaScript调用任何编译为WASM(WebAssembly模块)的代码。
TinyGo 特别适合用于WASM,因为它具有更小的运行时占用空间。(关于从JS调用WASM库的文章。)
旁注:Go项目 wazero 则走向了另一个方向:从Go调用WASM。
(给自己提个醒:我该开始好好理解一下WebAssembly了。)
一种常见的方式是将Go库编译为WebAssembly,然后在JavaScript中调用。以下是具体步骤:
- 编写Go代码并导出函数:
// main.go
package main
import "syscall/js"
func add(a, b int) int {
return a + b
}
func main() {
c := make(chan struct{}, 0)
js.Global().Set("goAdd", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
return add(args[0].Int(), args[1].Int())
}))
<-c
}
- 编译为WebAssembly:
GOOS=js GOARCH=wasm go build -o main.wasm main.go
- 在HTML中加载:
<!DOCTYPE html>
<script src="wasm_exec.js"></script>
<script>
const go = new Go();
WebAssembly.instantiateStreaming(fetch("main.wasm"), go.importObject)
.then((result) => {
go.run(result.instance);
// 调用Go函数
console.log(goAdd(5, 3)); // 输出8
});
</script>
另一种方式是通过子进程调用编译后的Go二进制文件:
// Node.js示例
const { spawn } = require('child_process');
const goProcess = spawn('./your-go-binary', ['arg1', 'arg2']);
goProcess.stdout.on('data', (data) => {
console.log(`输出: ${data}`);
});
goProcess.stderr.on('data', (data) => {
console.error(`错误: ${data}`);
});
对于需要高性能的场景,可以考虑使用gRPC-Web:
- Go服务端:
// server.go
package main
import (
"net/http"
"github.com/improbable-eng/grpc-web/go/grpcweb"
"google.golang.org/grpc"
)
func main() {
grpcServer := grpc.NewServer()
wrappedServer := grpcweb.WrapServer(grpcServer)
http.ListenAndServe(":8080", wrappedServer)
}
- JavaScript客户端:
// client.js
import { grpc } from "@improbable-eng/grpc-web";
const client = new YourServiceClient("http://localhost:8080");
const request = new YourRequest();
client.yourMethod(request, (err, response) => {
if (err) console.error(err);
console.log(response);
});
如果Go库提供了C接口,也可以使用node-ffi:
const ffi = require('ffi-napi');
const lib = ffi.Library('./libyourgo.so', {
'GoFunction': ['int', ['int', 'int']]
});
const result = lib.GoFunction(5, 3);
console.log(result); // 8
这些方法各有适用场景:WebAssembly适合浏览器环境,子进程调用适合Node.js本地执行,gRPC-Web适合网络服务,FFI适合系统级集成。


