DRYな備忘録

Don't Repeat Yourself.

GoでWASMでHello World

背景

  • 一応GoもやってるしWebのフロントエンドもある程度やっているのに、WASMなにも触ったこと無いのはよくないので触りたい
  • WASMというものが一体何なのか、何ができるかも知らない

tl;dr

  1. Goで書いたコードをwasmにするフラグをつけてビルドすると.wasmが手に入る
  2. 本質的には上記がすべてであるが
    1. このwasmをkickするためのwrapperなJSもGoは提供してくれている
    2. 好きなようにサーバを立てて、このwasmファイル、およびwrapperなJSがブラウザから読める状態にすればよい

参考

成果物

github.com

ログ

cd $GOPATH/src/github.com/otiai10
mkdir hello-go-wasm
cd hello-go-wasm
git init
go mod init
mkdir server
mkdir client

とりあえず以下のような感じでサーバつくった

.
├── client
└── server
    ├── main.go
    └── views
        └── index.html

つぎにWASMの準備

# wrapperなJSをGOROOTから持ってくる
cp "$(go env GOROOT)/misc/wasm/wasm_exec.js" ./server/static/js

index.htmlに以下を追加

<head>
   <script src="/public/js/wasm_exec.js"></script>
   <!-- 神経質に public/wasm に分けなくてもいいとは思いつつ -->
   <script>
       const go = new Go();
       WebAssembly.instantiateStreaming(fetch("public/wasm/main.wasm"), go.importObject).then((result) => {
           go.run(result.instance);
       });
   </script>
</head>

いよいよ、wasmになるであろうGoを書く。 ./client/main.goを以下のように書いた

package main

import "fmt"

func main() {
    fmt.Println("これがconsoleにprintされるん?")
}

んで、ビルド

GOOS=js GOARCH=wasm go build  -o ./server/static/wasm/main.wasm ./client/main.go

で、これをサーバに読ませる

go run server/main.go

f:id:otiai10:20201103130408p:plain
できたじゃん。ヤバ

かんたんだった。DOMの操作とかはsyscall/jsで出来そうなので、今回はいいや、となりました。

所感

DRYな備忘録として