Upgrade to Pro — share decks privately, control downloads, hide ads and more …

SpaGoでSPAを作ろう!

irieda
November 14, 2020

 SpaGoでSPAを作ろう!

GoのエコシステムだけでSPAを作るツールキットの紹介。
https://github.com/nobonobo/spago

本公開中:「Goで作るシングルページアプリケーション」
https://zenn.dev/nobonobo/books/85e605893d44ebe7dd3f

irieda

November 14, 2020
Tweet

More Decks by irieda

Other Decks in Programming

Transcript

  1. 2020/11/14 11:29 5 / 32 ϖʔδ http://localhost:8080/#page20 ηοτΞοϓ Go ࢖ͬͯΔਓͳΒ

    > go get github.com/nobonobo/spago/cmd/spago > spago Usage of spago: commands: new component scafold generate html to go for spago code generator server development http server deploy deploy static files ͨͬͨ͜Ε͚ͩͰ࢝ΊΒΕ·͢ɻ
  2. 2020/11/14 11:29 8 / 32 ϖʔδ http://localhost:8080/#page20 ϝΠϯϏϡʔίϯϙʔωϯτͷ࡞੒ spago new

    Top ↓ ग़ྗ ↓ top.go Top ίϯϙʔωϯτఆٛ top.html ۭͷ HTML ϑΝΠϧ
  3. 2020/11/14 11:29 9 / 32 ϖʔδ http://localhost:8080/#page20 HTML ͷهड़ top.html

    <body> <button>ԡ͢ͳΑʂ</button> <label>...</label> </body>
  4. 2020/11/14 11:29 10 / 32 ϖʔδ http://localhost:8080/#page20 main.go ͷ࡞੒ main.go

    ΛҎԼͷΑ͏ʹॻ͖·͠ΐ͏ɻ package main import "github.com/nobonobo/spago" func main() { spago.RenderBody(&Top{}) select {} }
  5. 2020/11/14 11:29 12 / 32 ϖʔδ http://localhost:8080/#page20 ϓϩδΣΫτϑΥϧμΛΈͯΈΑ͏ top_gen.go ͱ͍͏ϑΝΠϧ͕૿͍͑ͯ·͢ɻ

    sample/ !"" !"" frontend/ # # !"" !"" main.go # # !"" !"" top.go # # !"" !"" top.html # # $"" $"" top_gen.go <-- !"" !"" go.mod $"" $"" go.sum
  6. 2020/11/14 11:29 13 / 32 ϖʔδ http://localhost:8080/#page20 ൜ਓ͸ͩΕʁ ͜ΕΛ࡞ΔίϚϯυ͸ top.go

    ͷઌ಄ʹهड़͕͋Γ·͢ɻ package main import ( "github.com/nobonobo/spago" ) //go:generate spago generate -c Top -p main top.html type Top struct { spago.Core }
  7. 2020/11/14 11:29 14 / 32 ϖʔδ http://localhost:8080/#page20 ͜ͷίϚϯυʹΑΓ top_gen.go ͕࡞ΒΕ·͢

    spago generate -c Top -p main top.html ʮtop.htmlʯ->ʮTop ίϯϙʔωϯτ Render ϝιου ࣮૷ʯ func (c *Top) Render() spago.HTML { return spago.Tag("body", spago.Tag("button", spago.T(`ԡ͢ͳΑʂ`), ), spago.Tag("label", spago.T(`...`), ), ) }
  8. 2020/11/14 11:29 15 / 32 ϖʔδ http://localhost:8080/#page20 ։ൃαʔόʔͷڍಈ spago server

    ։ൃαʔόʔ͸ main.wasm Λཁٻ͞Εͨ৔߹ɺ go generate ./... go build -o main.wasm . Ҏ্ͷॲཧͯ͠ಘΒΕΔग़ྗΛϨεϙϯεͱͯ͠ฦ͢ ϦϩʔυͰ HTML ΍ WASM ͸ϦϏϧυ͞ΕΔ࢓૊Έ ͜ΕʹΑΓ SpaGo ϚʔΫΞοϓͷࣄ͸஌Βͳͯ͘΋͋ Δఔ౓ OK
  9. 2020/11/14 11:29 16 / 32 ϖʔδ http://localhost:8080/#page20 Top ίϯϙʔωϯτͷߋ৽ top.go

    ʹ Message ϓϩύςΟΛ૿΍͢ type Top struct { spago.Core Message string } top.html ͷϥϕϧςΩετʹͦͷϓϩύςΟΛࢦఆ <body> <button>ԡ͢ͳΑʂ</button> <label>{{c.Message}}</label> </body> ͋͞ɺϦϩʔυͯ͠ΈΑ͏ʂ
  10. 2020/11/14 11:29 17 / 32 ϖʔδ http://localhost:8080/#page20 ϥϕϧͷ಺༰͕ۭจࣈʹ ࣍͸ top.go

    ʹ OnClick ϝιουΛ૿΍͢ func (c *Top) OnClick(ev js.Value) { c.Message = "ԡͨ͠ͳʂ" spago.Rerender(c) } top.html ͷϘλϯʹ @click="{{c.OnClick}}" ͱ͍͏ଐੑΛ௥Ճ͠·͢ɻ <button @click="{{c.OnClick}}">ԡ͢ͳΑʂ</button> ͋͞ɺϦϩʔυͯ͠ΈΑ͏ʂ
  11. 2020/11/14 11:29 21 / 32 ϖʔδ http://localhost:8080/#page20 SpaGo ϚʔΫΞοϓͱ͸ʁ DOM

    Λ૊ΈཱͯΔ Go ίʔυهड़ ͪΐͬͱ֮͑Δ͜ͱଟͯ͘൥ࡶ spago generate ͕͓ख఻͍͢ΔΑʂ HTML هड़͔Β SpaGo ϚʔΫΞοϓΛੜ੒
  12. 2020/11/14 11:29 22 / 32 ϖʔδ http://localhost:8080/#page20 JS ར༻ίʔυͱ͸ʁ syscall/js

    Λར༻͢Δ Go ίʔυهड़ ͪΐͬͱ֮͑Δ͜ͱଟͯ͘൥ࡶ js2go͕͓ख఻͍͢ΔΑʂ JavaScript ͷهड़Λ Go ͷهड़ʹτϥϯεϨʔτ
  13. 2020/11/14 11:29 23 / 32 ϖʔδ http://localhost:8080/#page20 ଞͷτϐοΫ Router Action

    ͱ Dispatcher ίϯϙʔωϯτͷ࡞੒ͱެ։ API ࿈ܞ γϯάϧόΠφϦԽ Go Ͱ࡞ΔγϯάϧϖʔδΞϓϦέʔγϣϯ ͱ͍͏ຊެ։ͯ͠·͢ɻಡΜͰΈͯͶʂ
  14. 2020/11/14 11:29 24 / 32 ϖʔδ http://localhost:8080/#page20 Isomorphic ͳ։ൃ TypeScript/nodejs

    ͡Όͳͯ͘΋ SpaGo Ͱ΋Ͱ͖Δʂ όοΫΤϯυͱϑϩϯτΤϯυͷڞ௨ͷ JSON ఆٛΛར༻Մೳ WebSocket ܦ༝Ͱ JSON-RPC, gRPC Ͱͭͳ͙͜ͱ΋Մೳ
  15. 2020/11/14 11:29 25 / 32 ϖʔδ http://localhost:8080/#page20 SpaGo ͷ໨ࢦ͢ͱ͜Ζ Go

    ͷΤίγεςϜ͚ͩͰ։ൃΛՄೳʹ ඞཁͳ΋ͷΛۃྗӅ͞ͳ͍ ࠷଎Λ໨ࢦ͞ͳ͍͕ॏ͍ॲཧ΋࠾༻͠ͳ͍ ̍छྨͷϑΝΠϧʹෳ਺ݴޠهड़͸࠾༻͠ͳ͍ DSL ͰશͯදݱͰ͖ΔͷΛ໨ࢦ͞ͳ͍ TinyGo αϙʔτΛ TinyGo ͷޓ׵ੑ޲্ͱͱ΋ʹาΉ
  16. 2020/11/14 11:29 26 / 32 ϖʔδ http://localhost:8080/#page20 SpaGo ͷ࣮ྫ ͜ͷϓϨθϯςʔγϣϯ

    CLI Λ࡞ͬͨ http://github.com/nobonobo/spago-slides JS2Go ͱ͍͏αʔϏε( https://nobonobo.github.io/js2go/ ) ͓࢓ࣄͰ BLE σόΠεͷϩΨʔ΍Ϟχλʔ ͓࢓ࣄͰ BLE σόΠεͷϑΝʔϜ΢ΣΞϥΠλʔ on RaspberryPi
  17. 2020/11/14 11:29 27 / 32 ϖʔδ http://localhost:8080/#page20 WASM αΠζʹ͍ͭͯ αϯϓϧ໊

    Go Go+GZip TinyGo TinyGo+GZip spago/examples/simple 2.3MiB 683KiB 342KiB 146KiB spago.examples/todo 2.7MiB 717KiB - spago/examples/pwa 2.4MiB 701KiB 393KiB 170KiB spago/examples/forms 2.3MiB 678KiB 339KiB 143KiB spago/examples/spa 2.4MiB 719KiB 439KiB 185KiB Go ͷ৔߹+2MiB(GZip:500KiB)͘Β͍ͷ଍͔͕ͤࡌΔ ͱ͍͏͜ͱɻ TinyGo+GZip ͳΒαΠζ্ͷ໰୊͸ͳͦ͞͏ɻ ѹॖͨ͠ঢ়ଶͰαʔϒ͠ͳ͍ͱπϥΠ
  18. 2020/11/14 11:29 28 / 32 ϖʔδ http://localhost:8080/#page20 WASM ࣮૷ͷςετ͸ʁ GoͰWASM༻࣮૷ͷςετ

    NoboNobo͞ΜʹΑΔهࣄ zenn.dev Chrome ͱҎԼͷΠϯετʔϧΛߦ͏ͱී௨ʹ go test ͕࢖͑ΔΑ͏ʹͳΔɻ go get github.com/agnivade/wasmbrowsertest i=$(which wasmbrowsertest) mv $i $(dirname $i)/go_js_wasm_exec go env -w GOOS=js GOARCH=wasm go test . ཪͰϔουϨε Chrome Λಈ͔͠·͢
  19. 2020/11/14 11:29 29 / 32 ϖʔδ http://localhost:8080/#page20 TinyGo ʹ͍ͭͯ Go

    ͷαϒηοτͰ LLVM όοΫΤϯυɺݱঢ়҆ఆ൛: v0.15.0 ϚΠΫϩίϯϐϡʔλ޲͚͚ͩͲ WASM ग़ྗ΋αϙʔτ ·ͩͪΐͬͱͨ͜͠ͱͰίϯύΠϧͰ͖ͳ͍هड़͕͋Δ ಺෦ͷ IR ࣮૷ΛӶҙϦϥΠτதͰ͜Ε͕ࡌΕ͹͍ͩͿޓ׵͕޲্͢Δ༧ఆ ੒Ռ෺͸ຊՈʹൺ΂Δͱ 2MiB ΄Ͳখ͍͞ ͞Βʹ panic ϥϯλΠϜ࡟ͬͨΓɺGZip ͢Ε͹͔ͳΓίϯύΫτʹ
  20. 2020/11/14 11:29 30 / 32 ϖʔδ http://localhost:8080/#page20 ·ͱΊ Go ຊՈͷ

    WASM ग़ྗ͸αΠζ͕େ͖͍ ݱঢ়͸σεΫτοϓΞϓϦ୅ΘΓʹ࢖͏༻్޲͖ TinyGo ͕҆ఆಈ࡞͢Ε͹ར༻γʔϯ͕֦େ͢Δ ίϯύΠϧܕͳͷͰ༨ܭͳίʔυ͕ग़ྗʹࡌͬͯ͜ͳ͍ npm/webpack Λ࢖Θͳ͍ϑϩϯτΤϯυ։ൃ͸շద ґଘղܾ͕ܾఆతͰ҆ఆͯ͠ͱʹ͔͘Ϗϧυ͕ૣ͍