LoginSignup
0
0

More than 3 years have passed since last update.

golangでVuguを試してみた。

Last updated at Posted at 2019-08-17

最近、golangでwebassemblyに触れてみたのでその延長でvuguを試してみた。

Vugu

公式:https://www.vugu.org/
webassemblyでReactやVue風にUIを書くことができるらしい。

バージョン

  • go1.12.6

Make sure you have at least Go 1.12 installed

公式のGetting Startedを読んでみると少なくともgolangのバージョンは1.12である必要があるらしいので注意

お試し

Getting Startedをそのままなぞるのではつまらないので少し違った手順で試してみる。

構成

vugu-demo/
 ┣ root.vugu
 ┣ wasm_exec.js
 ┗ index.html

これだけ

手順

root.vuguを書く

<div class="my-first-vugu-comp">
    <button @click="data.Toggle()">Test</button>
    <div vg-if="data.Show">I am here!</div>
</div>

<style>
.my-first-vugu-comp { background: #eee; }
</style>

<script type="application/x-go">
type RootData struct { Show bool }
func (data *RootData) Toggle() { data.Show = !data.Show }
</script>

vugugenをビルド

$ pwd
/path/to/vugu-demo
$ git clone https://github.com/vugu/vugu.git
$ ls
index.html root.vugu vugu wasm_exec.js
$ cd ./vugu
$ go build cmd/vugugen/vugugen.go

root.vugu からgoのソースを生成するためのコマンドがあるのでビルドする。

root.vuguからgoのソースを生成

$ /path/to/vugu-demo/vugu/vugugen /path/to/vugu-demo
$ ls
go.mod index.html main_wasm.go root.go root.vugu vugu wasm_exec.js
main_wasm.go 一部抜粋
 18   rootInst, err := vugu.New(&Root{}, nil)
 19   if err != nil {
 20     log.Fatal(err)
 21   } 
 22   
 23   env := vugu.NewJSEnv("#root_mount_parent", rootInst, vugu.RegisteredComponentTypes())
 24   env.DebugWriter = os.Stdout
 25   
 26   for ok := true; ok; ok = env.EventWait() { 
 27     err = env.Render()
 28     if err != nil {
 29       panic(err)
 30     }
 31   }
  • 18行目:root.go で定義されているRootコンポーネントを生成する。

  • 23行目:webassemblyでDOMをレンダリングするための環境を生成する。idroot_mount_parentの要素にRootコンポーネントを展開する。

  • 26~30行目: レンダリングループ。イベントが発生するまでenv.EventWait()でブロックし、イベントが発生したらenv.Render()でレンダリング処理を行う。

wasmファイルのビルド

$ GOOS=js GOARCH=wasm go build -o ./main.wasm ./*.go
$ ls
go.mod      go.sum      index.html  main.wasm   main_wasm.go    root.go     root.vugu   vugu        wasm_exec.js

index.htmlを書く

index.html
  1 <!DOCTYPE html>
  2 <html>
  3   <head>
  4     <title>example</title>
  5   </head>
  6   <body>
  7     <div id="root_mount_parent">
  8       <div></div>
  9     </div>
 10     <script src="./wasm_exec.js"></script>
 11     <script>
 12       const go = new Go();
 13       WebAssembly.instantiateStreaming(fetch("./main.wasm"), go.importObject).then((result) => {
 14         go.run(result.instance);
 15       });
 16     </script>
 17   </body>
 18 </html>
  • 7~9行目: Rootコンポーネントが展開されるポイント。 id="root_mount_parent" が指定されている要素に必ず子要素が存在することに注意。 vugu/env-js.goのソースをみてみる。
github.com/vugu env-js.goより一部抜粋
150   c := e.rootInst
151   mountParentEl := document.Call("querySelector", e.MountParent)
152   if !mountParentEl.Truthy() {
153     return fmt.Errorf("failed to find mount parent using query selector %q", e.MountParent)
154   }
155 
156   vdom, css, err := c.Type.BuildVDOM(c.Data)
157   if err != nil {
158     return err
159   }
160   _, _ = vdom, css
161 
162   // do basic setup and ensure we have a css style element and a root element, in that order
163   mountChild1 := mountParentEl.Get("firstElementChild")

querySelectorid="root_mount_parent"の要素を取得したあと、firstElementChildで子要素の最初の要素を取得しようとしているため、展開するポイントに子要素が存在しない場合エラーを吐いてしまう。なぜこのようになっているのかわからないが、自分でhtmlを作成する場合は注意が必要。なお、公式のGetting Startedで使用しているsimplehttp ではベースとなるhtmlを自動的に提供してくれていますのでsimplehttpを使用する際には注意は不要です。

  • 10行目: wasm_exec.js読み込み

wasm_exec.js$(go env GOROOT)/misc/wasm内にあります。

  • 11~16行目: 前行程でビルドしたwasmファイルを読み込み

デプロイ

github.ioで適当にデプロイしてみる。以下URL
https://shorii.github.io/vugu-demo/

感想

最初index.html の展開ポイントに子要素が必要だということがわからなくてはまってしまった。やっぱりわからないことがあったらソースコードを読むことが重要ですね。

golang自体まだ触り始めたばかりなのでもっと面白いことができるようになりたい。

ソースコード

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0