英文:
Nodejs run WASM generated by Golang error but browser success
问题
我创建了一个名为WASM的Go文件:
package main
func main() {
println("Hello, world!")
}
然后,执行以下命令生成test.wasm
文件:
> GOOS=js GOARCH=wasm go build -o test.wasm ./test.go
我想在Node.js中运行WASM,参考Node.js与WebAssembly:
// test.js
const fs = require('fs');
const wasmBuffer = fs.readFileSync('./test.wasm');
WebAssembly.instantiate(wasmBuffer).then((wasmModule) => {
console.log(wasmBuffer);
});
错误信息:
node:internal/process/promises:279
triggerUncaughtException(err, true /* fromPromise */);
^
[TypeError: WebAssembly.instantiate(): Imports argument must be present and must be an object]
但是,我可以在浏览器中执行:
<html>
<head>
<meta charset="utf-8"/>
<script src="wasm_exec.js"></script>
<script>
if (!WebAssembly.instantiateStreaming) {
// polyfill
WebAssembly.instantiateStreaming = async (resp, importObject) => {
const source = await (await resp).arrayBuffer();
return await WebAssembly.instantiate(source, importObject);
};
}
const go = new Go();
let mod, inst;
WebAssembly.instantiateStreaming(fetch("test.wasm"), go.importObject).then(
async (result) => {
mod = result.module;
inst = result.instance;
await go.run(inst);
inst = await WebAssembly.instantiate(mod, go.importObject); // reset instance
}
);
</script>
</head>
<body></body>
</html>
环境:
-
Node.js: 16.15.1
-
Golang: go1.18.3 darwin/arm64
英文:
I create a go file as WASM:
package main
func main() {
println("Hello, world!")
}
Then, execute following command to generate test.wasm
:
> GOOS=js GOARCH=wasm go build -o test.wasm ./test.go
I want run WASM in Node.js, ref Node.js with WebAssembly:
// test.js
const fs = require('fs');
const wasmBuffer = fs.readFileSync('./test.wasm');
WebAssembly.instantiate(wasmBuffer).then((wasmModule) => {
console.log(wasmBuffer);
});
error message:
node:internal/process/promises:279
triggerUncaughtException(err, true /* fromPromise */);
^
[TypeError: WebAssembly.instantiate(): Imports argument must be present and must be an object]
But, I can execute in browser:
<html>
<head>
<meta charset="utf-8"/>
<script src="wasm_exec.js"></script>
<script>
if (!WebAssembly.instantiateStreaming) {
// polyfill
WebAssembly.instantiateStreaming = async (resp, importObject) => {
const source = await (await resp).arrayBuffer();
return await WebAssembly.instantiate(source, importObject);
};
}
const go = new Go();
let mod, inst;
WebAssembly.instantiateStreaming(fetch("test.wasm"), go.importObject).then(
async (result) => {
mod = result.module;
inst = result.instance;
await go.run(inst);
inst = await WebAssembly.instantiate(mod, go.importObject); // reset instance
}
);
</script>
</head>
<body></body>
</html>
environment:
-
Nodejs: 16.15.1
-
Golang: go1.18.3 darwin/arm64
答案1
得分: 4
最后,我找到了一种在Node.js上执行Golang WASM的方法:
// 注释掉这个块以避免死锁
// if (code === 0 && !go.exited) {
// // 死锁,使Go打印错误和堆栈跟踪
// go._pendingEvent = { id: 0 };
// go._resume();
// }
// 以下代码是为了避免死锁
const result = globalThis[func](...funcArgs);
console.log(result);
process.exit();
- 代码:https://github.com/riskers/nodejs-exec-go-wasm/blob/main/examples/golang/README.md
或者你可以使用tinyGo编译wasm。
- 代码:https://github.com/riskers/nodejs-exec-go-wasm/blob/main/examples/tinygo-wasmer/README.md
适用于Node和浏览器的通用cross-wasm
。
- 代码:https://github.com/riskers/nodejs-exec-go-wasm/blob/main/packages/cross-wasm/README.md
英文:
Finally, I found a way to execute Golang WASM on Node.js:
// commend the block avoid deadlock
// if (code === 0 && !go.exited) {
// // deadlock, make Go print error and stack traces
// go._pendingEvent = { id: 0 };
// go._resume();
// }
// below code is to avoid deadlock
const result = globalThis[func](...funcArgs);
console.log(result);
process.exit();
Or you can use tinyGo compile wasm.
Universal cross-wasm
for Node and Browsers.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论