Go EmbedでWASM埋め込み 2025/9/29 golang.tokyo #41
自己紹介 氏名:竹田 舜(たけだ しゅん) X: https://x.com/TKDDDDDS ⚠今日の内容は 仕事全然関係ないです!! 完全に趣味です 所属:株式会社ラクス AIエージェント課(元SRE課) (部署の記事タイトル:株式会社ラクス、AIエージェント開発専門組織を設立 ) 2023年新卒入社 3年目 仕事内容:インフラ寄り〜アプリ寄りまでなんでも! 趣味:ライブ見に行くこと(明日・明後日ヨルシカのライブが控えてるのでうきうき)
今日のテーマ Go Embed知ってますか?? ※https://pkg.go.dev/embed
色々なファイルを 埋め込み可能にするパッケージ
例(パッケージのドキュメントより引用) テキストファイル バイナリファイル import _ "embed" import _ "embed" //go:embed hello.txt //go:embed hello.txt var s string var b []byte print(s) print(string(b))
//go:embedをつけることで ファイルの埋め込みが可能
ポイント 格納したい変数の前にコメントをつけるだけで使える ファイルの埋め込みはコンパイル時に行われる ※templateエンジンと組み合わせたり色々使いみちあるが今日は省略
ここまでGo Embedの説明
じゃあWASMはどう埋め込むのか?
実際にWASM埋め込みを使ってるライブラリ go-pgquery(sqlのパーサー) https://github.com/wasilibs/go-pgquery/blob/10ac41983c0720ff96ff022fc5298a371e72316a/internal/wasm/wasm.go#L5 .soファイルを ダウンロードして 確認してみると たしかにWasmバイナリ WasmバイナリをGo Embedで読み込んでる
[]byteの変数として読み込むといけそう!!! //go:embed wasmのファイルパス var 変数名 []byte ↑読み込みはこれだけ!
真似すればできそう??
実際にお試し
TinyGoで作った WASM製足し算処理を実行する 流れ 1. コンパイル時にWASMを埋め込み 2. wazeroインスタンスを作成 3. WASMをwazeroに読み込み 4. 実行
できた!!が...
足し算だけだと面白くないので... JSを実行する例 QuickJSというJS Runtimeのwasm版を使ってJSコードを実行すると...
足し算だけだと面白くないので... JSを実行する例 QuickJSというJS Runtimeのwasm版を使ってJSコードを実行すると... 実行できた!※コードはGithubに載せとくので興味ある人はみてください TinyGoでつくったwasmバイナリじゃなくても実行できる!
Go側から呼び出してるので並行処理もできる! 10回繰り返しをさせてgoroutineを使った並行処理版と比較してみると... 当然だが早くなる! 左が直列、右が並列
wasmごと埋め込むメリット - Goバイナリ1つで完結できるようになりwasmファイルの添付が不要になる wazeroなどを使えばwasmランタイムもまるごと埋め込める ビルド時点でwasmファイルが固定され、差し替えられることがなく安全 ライブラリとして配布が可能になる - 例)go-pgqueryなどはこの形式 import "github.com/wasilibs/go-pgquery"で使用可能にできる - quickjsの例のようにGoの並行処理機能を活かして軽量にJS並行処理とかでき ちゃうかも??(全然wasm周り詳しくないのでwazero側の制約とかあったり全然軽量じゃな かったらすみません)
まとめ - Go Embedはファイルを埋め込めるパッケージ 埋め込むと1つのGoバイナリで完結できて配布しやすいのがメリット Goの機能もつかえる!!! 興味を持った人はぜひ試してネット上で発信してください!! (いろんなアイディア見たい!!)