add WASM blazor-like thing
This commit is contained in:
82
go/cmd/examples/go-wasm-web/server/main.go
Normal file
82
go/cmd/examples/go-wasm-web/server/main.go
Normal file
@@ -0,0 +1,82 @@
|
||||
// Command server runs the go-wasm-web example on kjol's reusable wasmdevserver:
|
||||
// it SSRs the app's static routes, hosts the /rsc server-component endpoint, and
|
||||
// hot-swaps the wasm into the browser on change. It shows the coupling
|
||||
// inversion — the framework (wasmdevserver) imports no app code; the app injects
|
||||
// Build/Render/Document here.
|
||||
//
|
||||
// Run it from THIS directory (the relative paths below are resolved against it):
|
||||
//
|
||||
// go run ./server # from cmd/examples/go-wasm-web
|
||||
package main
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
|
||||
"kjol/vdom"
|
||||
"kjol/wasmdevserver"
|
||||
|
||||
"gowasmweb/app"
|
||||
)
|
||||
|
||||
func main() {
|
||||
addr := flag.String("addr", ":8085", "listen address")
|
||||
watch := flag.Bool("watch", true, "watch sources, rebuild wasm, hot-reload")
|
||||
flag.Parse()
|
||||
|
||||
log.Fatal(wasmdevserver.Serve(wasmdevserver.Config{
|
||||
Addr: *addr,
|
||||
Dir: "./wwwroot",
|
||||
Watch: *watch,
|
||||
WatchDirs: []string{"app", "wasm", "../../../vdom", "../../../wasmruntime", "../../../rsc"}, // example + kjol engine
|
||||
Build: buildWasm,
|
||||
Render: render,
|
||||
Document: document,
|
||||
}))
|
||||
}
|
||||
|
||||
// render SSRs a static route's #app inner HTML; ok=false ships an empty #app
|
||||
// (client-rendered). It's the same neutral render the client runs, so the client
|
||||
// hydrates it.
|
||||
func render(path string) (string, bool) {
|
||||
if !app.StaticPaths[path] {
|
||||
return "", false
|
||||
}
|
||||
deps := app.Deps{Path: func() string { return path }} // Navigate is nil on the server
|
||||
return vdom.RenderHTML(app.Shell(deps, app.Routes(deps))), true
|
||||
}
|
||||
|
||||
// document wraps the server-rendered inner HTML in the page shell. No whitespace
|
||||
// between <div id="app"> and the markup, so hydration's childNodes line up. The
|
||||
// dev server injects the livereload script before </body> in watch mode.
|
||||
func document(inner string) string {
|
||||
return `<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
||||
<title>gowasm — a tiny Blazor-like engine</title>
|
||||
<link rel="stylesheet" href="/bootstrap.min.css" />
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">` + inner + `</div>
|
||||
<script src="/wasm_exec.js"></script>
|
||||
<script src="/bootstrap.js"></script>
|
||||
</body>
|
||||
</html>`
|
||||
}
|
||||
|
||||
// buildWasm runs the directive codegen (kjol/cmd/gowasmgen), then compiles
|
||||
// ./wasm to wwwroot/app.wasm. Returned combined output is shown in the browser
|
||||
// overlay on failure.
|
||||
func buildWasm() ([]byte, error) {
|
||||
if out, err := exec.Command("go", "run", "kjol/cmd/gowasmgen", "./app").CombinedOutput(); err != nil {
|
||||
return out, err
|
||||
}
|
||||
cmd := exec.Command("go", "build", "-o", filepath.Join("wwwroot", "app.wasm"), "./wasm")
|
||||
cmd.Env = append(os.Environ(), "GOOS=js", "GOARCH=wasm")
|
||||
return cmd.CombinedOutput()
|
||||
}
|
||||
Reference in New Issue
Block a user