参考
- サクッと Go → WebAssembly を試す - Qiita
- GolangでWebAssemblyを触る -Qiita
- [Go WebAssembly] First Wasm Program - Hello World
- Go WebAssembly Tutorial - Building a Calculator Tutorial | TutorialEdge.net
- go/misc/wasm at master · golang/go
- syscall/js: build constraints exclude all Go files in C:\Go\src\syscall\js · Issue #26598 · golang/go
- How do you serve a static html file using a go web server? - Stack Overflow
- Using Go for WebAssembly applications - JAXenter
- Go 1.11: WebAssembly for the gophers – Zenika
- templateタグを使う - Qiita
- go - print readable variables with golang - Stack Overflow
バージョン
- macOS Mojave Version 10.14.3
- go version go1.11.5 darwin/amd64
ソースコード
Hello World
main.go
package main
import "fmt"
func main() {
fmt.Println("Hello wasm!")
}
bash
GOARCH=wasm GOOS=js go build -o test.wasm main.go
wasmの動作サンプルがgoのインストールディレクトリにあったのでそれを使いました
bash
sudo cp /usr/local/go/misc/wasm/wasm_exec.html .
sudo cp /usr/local/go/misc/wasm/wasm_exec.js .
sudo chmod 666 wasm_exec.html wasm_exec.js
簡単にサーバーを作成
server.go
package main
import (
"net/http"
)
func main() {
http.Handle("/", http.FileServer(http.Dir("./")))
http.ListenAndServe(":8080", nil)
}
bash
go run server.go
http://localhost:8080/wasm_exec.html にアクセスし、Runボタンを押すとgoでWebAssemblyを動かせたのを確認できました
このサンプルの実行環境を元に、TodoListを作っていこうと思いますm(_ _)m
TodoList作成
wasm_exec.html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Go wasm</title>
</head>
<body>
<form action="" method="post" id="add">
<input type="text" id="addText">
<input type="submit" value="submit" id="">
</form>
<ul id="todos"></ul>
<template id="todo">
<li>
<input type="checkbox" name="" class="todoCheck">
<span class="todoBody">予定ホゲホゲ</span>
<a href="#" class="todoDelete">delete</a>
</li>
</template>
<script src="wasm_exec.js"></script>
<script>
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);
});
</script>
</body>
</html>
main.go
package main
import (
"syscall/js"
)
func load() {
document := js.Global().Get("document")
templateElement := document.Call("getElementById", "todo").Get("content")
document.
Call("getElementById", "add").
Call("addEventListener", "submit", js.NewEventCallback(js.PreventDefault, func(e js.Value) {
if(document.Call("getElementById", "addText").Get("value").String() == "") {
return
}
// 新しいtodo用のDOMを作成
cloneElement := templateElement.Call("cloneNode", true)
// チェックボックスのイベント設定
cloneElement.
Call("querySelector", ".todoCheck").
Call("addEventListener", "change", js.NewEventCallback(js.PreventDefault, func(e js.Value) {
e.Get("target").
Get("parentNode").
Call("querySelector", ".todoBody").
Get("style").
Set("text-decoration", map[bool]string{true: "line-through", false: "none"}[e.Get("target").Get("checked").Bool()])
}))
// todoの内容を設定
cloneElement.
Call("querySelector", ".todoBody").
Set("textContent", document.Call("getElementById", "addText").Get("value").String())
// 削除イベントを設定
cloneElement.
Call("querySelector", ".todoDelete").
Call("addEventListener", "click", js.NewEventCallback(js.PreventDefault, func(e js.Value) {
if(js.Global().Get("confirm").Invoke("削除しますか?").Bool()) {
e.Get("target").
Get("parentNode").
Call("remove")
}
}))
// 新しいtodoをhtmlに表示
document.Call("getElementById", "todos").Call("appendChild", cloneElement)
// 入力ボックスを空にしておく
document.Call("getElementById", "addText").Set("value", "")
}))
}
func main() {
c := make(chan struct{}, 0)
println("WASM Go Initialized")
load()
<-c
}
なんとかtodolistを作るまでできました。
最後まで見ていただいてありがとうございましたm(_ _)m