All Projects → nobonobo → wecty

nobonobo / wecty

Licence: BSD-2-Clause License
Frontend ToolKit for Go and TinyGo.

Programming Languages

go
31211 projects - #10 most used programming language

Projects that are alternatives of or similar to wecty

Self Learning Materials For Blazor Jp
C# で Single Page Web アプリを開発するフレームワーク「Blazor」の WebAssembly 版 (client-side 版) の自習教材です。
Stars: ✭ 93 (+173.53%)
Mutual labels:  spa, wasm
Tinygo
Go compiler for small places. Microcontrollers, WebAssembly (WASM/WASI), and command-line tools. Based on LLVM.
Stars: ✭ 9,068 (+26570.59%)
Mutual labels:  wasm, tinygo
Zwitterion
A web dev server that lets you import anything*
Stars: ✭ 514 (+1411.76%)
Mutual labels:  spa, wasm
Spasm
Write single page applications in D that compile to webassembly
Stars: ✭ 129 (+279.41%)
Mutual labels:  spa, wasm
Rustmart Yew Example
Single Page Application (SPA) written using Rust, Wasm and Yew
Stars: ✭ 196 (+476.47%)
Mutual labels:  spa, wasm
spago
SpaGo is toolkit for Single Page Application.
Stars: ✭ 33 (-2.94%)
Mutual labels:  spa, tinygo
Prism
Build frontend web apps with Ruby and WebAssembly
Stars: ✭ 251 (+638.24%)
Mutual labels:  spa, wasm
imgalign
Webapplication for image stitching and aligning
Stars: ✭ 162 (+376.47%)
Mutual labels:  spa, wasm
interp
Interpreter experiment. Testing dispatch methods: Switching, Direct/Indirect Threaded Code, Tail-Calls and Inlining
Stars: ✭ 32 (-5.88%)
Mutual labels:  wasm
badaso
The API & platform builder, build your apps 10x faster even more, it's open source & 100% free !
Stars: ✭ 650 (+1811.76%)
Mutual labels:  spa
wasm-nginx-module
Run Wasm in OpenResty/Nginx
Stars: ✭ 55 (+61.76%)
Mutual labels:  wasm
async-script-loader
Asynchronous script loading for SPAs
Stars: ✭ 15 (-55.88%)
Mutual labels:  spa
runno
Browser-based code runner that can be embedded as an iframe or used as a library.
Stars: ✭ 211 (+520.59%)
Mutual labels:  wasm
warpy
WebAssembly interpreter in RPython
Stars: ✭ 54 (+58.82%)
Mutual labels:  wasm
holyc
An easy to use C++ to WASM compiler (Highly-experimental)
Stars: ✭ 33 (-2.94%)
Mutual labels:  wasm
blazor-ui
A collection of examples related to Telerik UI for Blazor Components: https://www.telerik.com/blazor-ui
Stars: ✭ 182 (+435.29%)
Mutual labels:  wasm
rustwasmc
Tool for building Rust functions for Node.js. Combine the performance of Rust, safety and portability of WebAssembly, and ease of use of JavaScript.
Stars: ✭ 97 (+185.29%)
Mutual labels:  wasm
vuetibook
Integrating Vue.js, Vuetify and Storybook
Stars: ✭ 16 (-52.94%)
Mutual labels:  spa
cakephpvue-spa
A CakePHP + VueJS single page application skeleton/boilerplate.
Stars: ✭ 40 (+17.65%)
Mutual labels:  spa
jRouting
Great routing mechanism for client-side web applications
Stars: ✭ 16 (-52.94%)
Mutual labels:  spa

Wecty

Wecty: フロントエンドツールキット for Go and TinyGo

  • Wecty は Vecty(github.com/gopherjs/vecty) のアイディアを元にしています
  • Wecty は Vecty よりも単純に実装されました
  • Wecty は WASM アーキテクチャのみをサポートします

方針

  • 基本的な機能を一通り含みます
  • リッチな機能や冗長な機能は採用しません
  • それにより出力される WASM サイズを小さく保ちます
  • 描画の最速を目指したりはしない

機能

  • SetTitle: ドキュメントタイトルの変更
  • AddStylesheet: スタイルシートの追加
  • AddScript: スクリプトの追加
  • AddMeta: メタヘッダの追加
  • RenderBody/Rerender: ボディコンポーネントの描画とコンポーネントの再描画
  • ネストされたコンポーネントのサポート
  • Mount/Unmount: マウントとアンマウントタイミングのフック
  • Tag: HTML タグのマークアップ
  • Attr: タグの属性をマークアップ
  • Class: タグのクラスをマークアップ
  • Event: タグのイベントをマークアップ
  • Router: シンプルな SPA ルーター(URL のハッシュ利用)
  • Utilities:
    • wecty generate: go-generate 用ツール、HTML 記述から Go のコードを生成
    • wecty server: 開発用サーバー

基本の使い方

ツールのセットアップ

go get github.com/nobonobo/wecty/cmd/wecty

ファイル群の準備

  • 以下のファイル(後述)を作成する
    • top.go
    • top.html
    • main.go
  • go mod init sample

top.html

<form @submit="{{c.OnSubmit}}">
  <button>Submit</button>
</form>

以下のコマンドを実行した場合、

wecty generate -c TopView top.html

top_gen.go が生成されます

package main

import (
  "github.com/nobonobo/wecty"
)

func (c *TopView) Render() wecty.HTML {
  return wecty.Tag("form",
    wecty.Event("submit", c.OnSubmit),
    wecty.Tag("button", vecty.Text("Submit")),
  )
}

以下のような Go コードを手書きで書いておくことでコンポーネントとして利用可能になります。

top.go

package main

import (
  "github.com/nobonobo/wecty"
)

type TopView struct {
  wecty.Core
}

func (c *TopView) OnSubmit(ev js.Value) interface{} {
  println("submit!")
  return nil
}

また以下の記述を top.go に加えておくと go generate で wecty generate が自動的に走るようになります。

//go:generate wecty generate -c TopView -p main top.html

main.go

package main

import (
  "github.com/nobonobo/wecty"
)

func main() {
  wecty.RenderBody(wecty.Tag("body", &TopView{}))
  select {}
}

あとはwecty serverを起動しておけば、 http://localhost:8080をブラウザで開くだけで top_gen.go が生成され WASM がビルド&サーブされブラウザで動作を開始する

開発の進め方

  • 上記のセットアップが完了したならば
  • top.html の編集ー>ブラウザリロードで反映結果を確認できます
  • top.go や main.go を修正後、ブラウザリロードで修正後の wasm モジュールの挙動を確認できます

Q&A

  • Q: なぜ Vecty とは別に作ったの?

    A: GopherJS の開発が停滞しつつあること、Vecty は GopherJS と Go 両対応により複雑な実装になっている。

  • Q: Router はなぜハッシュベース?

    A: URL を書き換えるスタイルはプロキシサーバーの URL 割り当てと整合をとる必要がある。ハッシュベースは単一の URL を振り向けるだけで動作する。つまり、SPA コンテンツを S3 に置いた場合でも動作する。

  • Q: Vecty のように prop や event パッケージを設けないのはなぜ?

    A: 基本のマークアップは wecty generate の出力に任せるのでマークアップの容易さは無用だった。それにそれらのパッケージが WASM サイズの肥大化を招いていた。

  • Q: wecty generate のマークアップ機能が足りないのはなぜ?

    A: 頑張っても Go の手書きの自由度を超えることはできない。ユーザーは wecty generate で済ますか Go のコードで細かく書いてコンポーネントを実装するかを使い分けてもらいたい。

  • Q: コンポーネントより細かい単位の最適な DOM ツリーの更新をしないのはなぜ?

    A: 軽量な実装で仮装 DOM を実装した。賢くすることで描画更新は早くなるかもしれないが、WASM サイズが膨れてしまうことは避けたかった。速度を極力落とさない作りはユーザーがチャレンジできる。それはコンポーネントの粒度を小さく保つこと。

コンポーネントに成れる構造体の条件

  • wecty.Core を埋め込みした構造体定義
  • Render() wecty.HTMLメソッドを持つこと

DOM ツリーのマークアップ

コンポーネント.Render() HTMLメソッドを実装するには 単一の wecty.Tag(...)の戻り値を return するように記述する。

func (c *コンポーネント) Render() HTML {
  return wecty.Tag(...)
}

wecty.Tag 関数の定義は以下の通り

wecty.Tag(tagName, markups ...wecty.Markup) *Node

tagName には HTML タグ名を渡す。markups には以下の記述を書く。

Markup になれるもの一覧

  • wecty.Attr(...)の戻り値(親 Tag の属性値になる)
  • wecty.Class{}値(親 Tag の classList 値になる)
  • wecty.Event(...)の戻り値(親 Tag にイベントリスナーを追加)
  • wecty.Text(...)の戻り値(子ノードを追加)
  • wecty.Tag(...)の戻り値(子ノードを追加)
  • Component を満たすオブジェクト(子ノードを追加)

ユーティリティ

wecty いくつかのサブコマンドをもつユーティリティ

  • wecty generate: HTML 記述から Wecty 用の Go コードを生成するツール
  • wecty server: 開発用簡易 HTTP サーバー

wecty generate

Usage of generate:
  -c string
    	component name
  -o string
    	output filename
  -p string
    	output package name (default "main")
  • default output filename=basename_gen.go
  • default package name=main
  • require component name

HTML ライクなマークアップの基本

<body></body> -> wecty.Tag("body")

属性マークアップ

<h1 id="title">Title</h1>:

wecty.Tag("h1",
  wecty.Attr("id", "title"),
  vecty.Text("Title"),
)

Class マークアップ

<h1 class="title large">Title</h1>:

wecty.Tag("h1",
  wecty.Class{
    "title": true,
    "large": true,
  },
  vecty.Text("Title"),
)

イベントマークアップ

<form @submit="{{c.OnSubmit}}">
  <button>Submit</button>
</form>
wecty.Tag("form",
  wecty.Event("submit", c.OnSubmit),
  wecty.Tag("button", vecty.Text("Submit")),
)

RAW 記述

<import>github.com/nobonobo/examples/todo/components</import>
<div><raw>&components.Item{}</raw></div>
import (
  "github.com/nobonobo/examples/todo/components"
)
...
  return wecty.Tag("div",
    &components.Item{},
  )
...

wecty server

開発用簡易 HTTP サーバー

Usage of server:
  -addr string
    	listen address (default ":8080")
  -p path=endpoint
      add reverse proxy rule (allow multiple rules)
  -tinygo
    	use tinygo tool chain

機能

  • 静的コンテンツのサーブ
  • "main.wasm"を要求されるとその該当フォルダで go-generate と WASM のビルド、gzip が行われその結果をサーブします
  • index.html が無いところで要求されたら標準的な WASM 読み込み用 HTML を返します
  • "wasm_exec.js"リソースが要求されたら適切な wasm_exec.js をサーブします
  • 指定パスへのアクセス要求を別の Web サーバーへ転送します(リバースプロキシー)

コマンドオプション

  • -addr: 開発サーバーのリッスンアドレスの指定
  • -p: 転送ルールの追加(複数指定可能)
  • -tinygo: WASM ビルドに tinygo を使う

例:

wecty server -addr :8080 -p /api/=http://localhost:9001

バックエンドサーバーを http://localhost:9001 にて動作させた状態で開発を進める場合などで使います。

出力サイズ

Todo サンプルのコンパイル事例

ツール WASM サイズ gzipped
Go 2.8MiB 787.2KiB
TinyGo 374KiB 154KiB

既知の問題

  • TinyGo コンパイラはまだ Go-Module サポートがありません。GOPATH、GO111MODULE=off などの環境変数設定が必要です
  • TinyGo の WASM 出力は js.finalizeRef が未実装なためメモリーリークが起こりえます
  • TinyGo 0.13.1 は log.Print 系を使うとデッドロックするバグがあります(dev 版では修正済み?)

今後の機能追加

  • 条件別マークアップ機能の提供
  • デプロイ用の静的ファイルセットをエクスポートする支援機能の提供
  • 新規プロジェクト生成機能の提供
  • コマンドツールの統合&サブコマンドによる多機能化
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].