2025-11-19 (水)
* goja
Goで実装されたJavaScriptエンジンのgojaがいつのまにか比較的モダンなJSを実行できるようになっていた。
https://github.com/dop251/goja
README の最初に ECMAScript 5.1(+) とか書かれているけど、実施はES2017あたりまでサポートされていそう?(モジュールは無い)
async/awaitとかも実装されている。goja自体にevent loopが無いのでそのままだと非同期処理を実行できないけど、 https://github.com/dop251/goja_nodejs にeventloopパッケージがある。
ただ、nodejs互換の環境を作る用途で実装されてるようなので、NewEventLoop()内で色々追加されてしまったり、RunしないとRuntimeオブジェクトを取れないのと、Go側で作ったPromiseとかは自分で管理しないといけないのが不便。最終的には自前で実装したほうが無難かもしれない。
package main import ( "github.com/dop251/goja" "github.com/dop251/goja_nodejs/eventloop" ) const SCRIPT = ` class AsyncTest { async run() { for (let i = 0; i < 10; i++) { await new Promise((r) => setTimeout(r, 200)); console.log(i); } } } (new AsyncTest()).run(); ` func main() { loop := eventloop.NewEventLoop() loop.Run(func(vm *goja.Runtime) { _, err := vm.RunString(SCRIPT) if err != nil { panic(err) } }) }
今までquickjsのbindingを使うのが無難だと思ってたけど、CGOが必要になってしまうのと、パフォーマンスが微妙だった。gojaはGoの上で動作しているのでシンプルな実装のわりに実行速度が速そう。