Chapter 02

SpaGoを作った理由

NoboNobo
NoboNobo
2020.11.03に更新

Goを使ったフロントエンドの作成にはGopherJSを使うかWASM出力を使うことでトライできます。
また、GopherJSとWASM出力の両対応のフロントエンドツールキット「Vecty」というものがあります。

ただ、GopherJSは開発がGo1.12対応で停滞しており、事実上GoのWASM出力しかブラウザで動作するコードは出力できない状況になりました。VectyはGopherJSとWASMの両対応に伴う複雑さがあり、近年のGoのバージョンアップごとに動かなくなる&新バージョン対応が繰り返されていますが、Goの最新バージョンへの追従のディレイは長くなる一方です。今後安定してブラウザで動くフロントエンドツールキットが欲しいという動機で「SpaGo」を作りました。

おそらく、堅牢に膨大な資産が使いたいのなら御三家を埋め込んだ環境をベースに御三家の機能を呼び出せるラッパーの形にするのが実用性としては高いとは思いますが、Goに慣れてしまった身としてnpm依存があまりにも辛いと感じてしまいます。

ちょっとしたものを作ろうにもかなり多くの依存を引き込んで、その依存をその後メンテするのが大変すぎるのです。Goのエコシステムはよくできていてメジャーバージョンにより互換が保たれるし、最小の依存しか引き込まないという特徴があります。バージョンロックし忘れて数ヶ月後再ビルドできなくなったりということが起きにくいエコシステムなのです。そして何よりビルドがかなり早いです。

このような特徴を生かしつつ、サクサクSPAを構築したくて「SpaGo」をつくりました。
必要最小限の機能は内包しているのでシンプルなSPAであればnpm依存せずにSPAを構築できると思います。(ただし、複雑だったりいろんなJS資産を使いたい場合は避けられなくなるとは思います)

SpaGoは以下のポリシーで作成されています。

  • Goの依存解決機構だけで開発できる様にする
  • Goの考え方にならって必要最小限な機能だけを用意する
  • コード補完の恩恵を最大限得るため、複数の言語を一つのファイルにミックスして記述するスタイルを避けたデザイン
  • Goコード記述によるSpaGoマークアップでコンポーネントを構築する
  • HTMLからSpaGoマークアップを生成するツールをバンドル
  • SpaGoマークアップの全てをHTMLから生成する機能はない
  • シンプルなコンポーネントはHTMLベースで記述
  • 複雑なコンポーネントはSpaGoマークアップをハンドライティング
  • 差分でDOMアップデートする機能を持つ
  • 遅くなる様な機能を採用しないが、最速を目指しているわけではない
  • ハッシュによるルーター、IoC用ディスパッチャーも用意する
  • 暗黙の挙動をなるべく入れ込まない(つまり明示的に書いた事以上のことは行わない)
  • それによりWASM出力サイズを抑える
  • WASM出力だけをサポートする

シンプルさを優先してはいますが、必要な知識がどうしても多層化してしまいました。

  1. SpaGoの機能セットを用いた仮想DOMツリー構築の知識
  2. 上記をHTMLから生成するための簡易DSLの知識
  3. JS相当の処理をGo記述で書くための知識
  4. 上記をJSコードから生成するための簡易トランスレータ

1.と3.は高度なことを実装するときに必要な知識です。
シンプルな実装であれば2.や4.を利用する知識だけで1.や3.は自動生成できるので、
1.や3.の知識がなくても大まかなものを実装することはできるようになっています。
繊細なものを作る時には1.や3.の知識が必要になってきます。