add WASM blazor-like thing
This commit is contained in:
71
go/cmd/examples/go-wasm-web/README.md
Normal file
71
go/cmd/examples/go-wasm-web/README.md
Normal file
@@ -0,0 +1,71 @@
|
||||
# go-wasm-web — example app for the gowasm engine
|
||||
|
||||
A runnable example of kjol's **gowasm** engine: author UI **components in pure
|
||||
Go**, compiled to **WebAssembly**, with **SSR + hydration**, **Next.js-style
|
||||
server components**, layouts, and a **flash-free, state-preserving hot reload**.
|
||||
No custom markup, no JSX — just Go. The engine lives in top-level kjol packages
|
||||
(`kjol/go/{vdom,wasmruntime,rsc,wasmdevserver}`); this directory is only the app
|
||||
that consumes them.
|
||||
|
||||
## Run it
|
||||
|
||||
```sh
|
||||
cd cmd/examples/go-wasm-web
|
||||
go run ./server # codegen + SSR + hot reload at http://localhost:8085
|
||||
```
|
||||
|
||||
Open http://localhost:8085. `/` and `/about` use the light **public** layout,
|
||||
`/chart` and `/server` use the dark **app** layout. Edit any `.go` file and the
|
||||
browser hot-swaps the new wasm **without a full reload or a flash**, preserving
|
||||
page state; a build failure shows the Go compiler output as an overlay.
|
||||
|
||||
(`build.sh` does a one-off build instead of running the dev server.)
|
||||
|
||||
## This is a separate module
|
||||
|
||||
`go.mod` here declares its own module (`gowasmweb`) with `replace kjol => ../../..`,
|
||||
so the app's `go-chart` dependency (and freetype / x/image) stays out of kjol —
|
||||
the engine packages (`vdom`, `wasmruntime`, `rsc`, `wasmdevserver`) are
|
||||
**stdlib-only**. `go build ./...` at the kjol root does not descend into this
|
||||
nested module; build it from this directory.
|
||||
|
||||
## Layout
|
||||
|
||||
```
|
||||
app/ the application — neutral, standalone functions (no central struct)
|
||||
pages.go Deps + Shell + App/Public layouts + nav + Counter + pages
|
||||
chart.go Chart page (go-chart, renders on both sides)
|
||||
server_counter.go //gowasm:server component (server-only; clicks-over-time chart)
|
||||
*.gen.go GENERATED by kjol/cmd/gowasmgen (routes, layout dispatch, stubs)
|
||||
wasm/ the js/wasm client entry point (main_native.go is a host stub)
|
||||
server/ the dev-server main: injects Build/Render/Document into wasmdevserver
|
||||
wwwroot/ bootstrap.js, bootstrap.min.css (+ generated wasm_exec.js, app.wasm)
|
||||
```
|
||||
|
||||
## How it maps onto the engine (top-level `kjol` packages)
|
||||
|
||||
| Engine package | Role | This app's use |
|
||||
|---|---|---|
|
||||
| `kjol/vdom` | neutral virtual DOM (native + wasm): `VNode`, builders, `Signal`, `RenderHTML` | pages build `*VNode`; `server` SSRs with `vdom.RenderHTML` |
|
||||
| `kjol/wasmruntime` | wasm client runtime: reconcile, `Run`/`Hydrate`, router, fetch, HMR state | `wasm/main.go` calls `Hydrate`/`Run` |
|
||||
| `kjol/rsc` | stateless server components over HTTP (gob) | `//gowasm:server` + the generated client stub |
|
||||
| `kjol/wasmdevserver` | reusable dev server: SSR, `/rsc`, hot reload, error overlay | `server/main.go` fills a `wasmdevserver.Config` |
|
||||
| `kjol/cmd/gowasmgen` | directive codegen → `app/*.gen.go` | run by `buildWasm` and `//go:generate` |
|
||||
|
||||
The **golden rule** holds: `wasmdevserver` imports no app code. The app injects
|
||||
`Build` (how to compile the wasm), `Render` (SSR a route → HTML), and `Document`
|
||||
(wrap it in a page) via `wasmdevserver.Config` — the same coupling inversion kjol
|
||||
uses elsewhere.
|
||||
|
||||
## Directives (expanded by `gowasmgen` at build time)
|
||||
|
||||
```go
|
||||
//gowasm:page / static layout=public // a route; `static` SSRs it, `layout=` wraps it
|
||||
func HomePage(d Deps) func() *VNode { ... }
|
||||
|
||||
//gowasm:layout public // chrome for pages that opt into layout=public
|
||||
func PublicLayout(d Deps, content *VNode) *VNode { ... }
|
||||
|
||||
//gowasm:server // runs on the server; calling it looks identical
|
||||
func ServerCounter() func() *VNode { count := NewSignal(0); ... }
|
||||
```
|
||||
Reference in New Issue
Block a user