Go + WebAssemblyを活用する / Using Go and WebAssembly

5e511bb6d01d856b4ec7a0e5b1f6a2f0?s=47 syumai
June 14, 2019

Go + WebAssemblyを活用する / Using Go and WebAssembly

5e511bb6d01d856b4ec7a0e5b1f6a2f0?s=128

syumai

June 14, 2019
Tweet

Transcript

  1. Go + WebAssemblyを活用する mercari.go #8 (6/14) syumai

  2. 自己紹介 syumai merpay Backend Developer (2018/5~) 趣味でJavaScript / TypeScript (Deno)

    をちょこちょこ書いてます
  3. 最近やった事

  4. Software Designに記事を書きました Software Design 2019年6月号 GoとWebAssemblyで遊ぼう ブラウザからアップロードしたファイルをcompress/gzipで圧縮す る方法を紹介してます

  5. Go Playgroundにタブを追加するChrome拡張を作った Go Playgroundが複数ファイル編集に対応していたのでタブを作っ てみました React Hooks + Redux +

    TypeScript 動画をTwitterに貼ってます
  6. 本題

  7. Go + WebAssemblyを活用する

  8. 今日は、気軽にGoのwasmを使っていく コツを紹介します

  9. もう使ってみた方はいらっしゃいますか?

  10. どんな事が出来るのか?

  11. 先日の出来事

  12. #zp‑syumaiにて

  13. None
  14. 社内で雑に依頼が飛んできた

  15. Goでしか出来ないことをブラウザでやる

  16. WebAssemblyがめっちゃハマりそう

  17. やりました

  18. time formatter の Demo https://syumai.github.io/go‑wasm‑playground/time/index.html

  19. どうやっているのか?

  20. まず、Goのwasmについておさらい

  21. Goのwasmの使い方 buildオプションを設定する GOOS=js GOARCH=wasm .wasm ファイルが生成され、JavaScriptから呼び出し、Web上 で実行できるようになる syscall/js packageを使う JavaScript側のObjectを参照したり、関数を呼んだり出来る

    詳しくはSoftware Design 6月号に書いてます(懇親会とかでも聞いてくだ さい!)
  22. 改めてtime formatterに戻ります

  23. ディレクトリ構成 time ├── formatter │ └── formatter.go ├── index.html ├──

    index.js ├── index.wasm └── main.go
  24. formatter package

  25. formatter packageでやっている事 ボタンクリック時に動かす関数を書く HTMLをゴリゴリ組み立てる ボタンを取得、クリックしたときの動作を設定する

  26. ボタンクリック時に動かす関数を書く formatter/formatter.go Formatter structのメソッドにしています

  27. HTMLをゴリゴリ組み立てる formatter/formatter.go JavaScript側のdocument Objectへの参照を作っておいて、 insertAdjacentHTML して突っ込みます

  28. ボタンを取得、クリックしたときの動作を設定する formatter/formatter.go div.New などは、指定したセレクタで getElementById する関 数です

  29. main.go

  30. main.goでやっている事 formatterを初期化して呼ぶだけ

  31. これで動いた

  32. けどつらみが…

  33. 今の構成で辛いところ ├── formatter │ └── formatter.go => syscall/js に依存している ├──

    index.html ├── index.js ├── index.wasm └── main.go
  34. syscall/jsに依存している GOOS=js GOARCH=wasmでしかコンパイル出来ないコードになっ てしまう

  35. syscall/jsに依存している GOOS=js GOARCH=wasmでしかコンパイル出来ないコードになっ てしまう => go testが動かせない!

  36. DOM操作をGoで行っている JavaScriptのdomのラッパーを書かないと辛い コールバックの処理を書くのがGoだと結構大変 https://github.com/syumai/go‑wasm‑playground/tree/master/dom

  37. Go + wasmでプロジェクトを作る時のコツ

  38. Go + wasmでプロジェクトを作る時のコツ コアの機能のpackageを切り出す main packageだけをsyscall/jsに依存させる

  39. さらに踏み込むと Go側はGoで行いたい処理に集中すべき DOM操作はJavaScriptで行うようにする

  40. この構成で作ったプロジェクト

  41. ojichat‑web

  42. 今話題のpackage greymdさんのojichatをwasmにしてWebページに組み込みます https://github.com/greymd/ojichat

  43. 知らない方のためのDemo https://github.com/syumai/ojichat‑web

  44. やった事 使いたい機能だけをExportするpackageを作る ojichatから必要な機能だけをメソッドとしてExportするstruct を宣言 JavaScript側のグローバル変数に使いたい機能を設定する 上記のstructをマッピングするJavaScriptのObjectを作る

  45. ディレクトリ構成 ojichat-web ├── ojichat | ├── ojichat.go => syscall/js に依存しない

    │ └── ojichat_test.go ├── go.mod ├── go.sum ├── index.html ├── main.go ├── main.wasm └── wasm_exec.js
  46. やった事を追っていきます 使いたい機能だけをExportするpackageを作る JavaScript側のグローバル変数に使いたい機能を設定する

  47. 使いたい機能だけをExportするpackageを作る ojichat/ojichat.go ojichatのgeneratorをimport OjiChat structを宣言

  48. 使いたい機能だけをExportするpackageを作る ojichat/ojichat.go Generate / TalkTo メソッドを公開

  49. JavaScript側のグローバル変数に使いたい機能を設定す る main.go OjiChat structを初期化するコンストラクタを作る

  50. JavaScript側のグローバル変数に使いたい機能を設定す る main.go グローバル変数としてOjiChatを設定

  51. ブラウザのコンソールでDemo

  52. DOM操作は全てJavaScript側に寄せています

  53. DOM操作は全てJavaScript側に寄せています

  54. 注意点 このコンストラクタの作り方だとメモリが解放されないので注意 JavaScript側でGo側のstructへの参照を持っている時の処理は追い きれていないです…

  55. testも動く! Demo

  56. まとめ wasmのpackageはコア機能を切り離したほうがよいです syscall/jsはmain packageのみに依存させましょう テスト可能になります Go側でDOM操作までやるほど頑張らず、JavaScript側に寄せたほ うがよいです

  57. と言いつつ Goだけで実装した簡易的な仮想DOMの実装を作っています https://github.com/syumai/go‑hyperscript ToDoリストも作れました Vue likeなGoのFrontendフレームワークのVuguなどもあります もっとGoだけで書きやすくなれば最高!

  58. wasmを活用してGoをより楽しんでいきまし ょう!

  59. ご静聴ありがとうございました!