Add hot reload for development
Implement automatic rebuild and browser reload during development:
- File watcher monitors .go files for changes with configurable extensions
- Builder compiles Go source to WASM on file changes
- LiveReload WebSocket server notifies connected browsers to reload
- DevServer combines all components for easy development setup
- HTML injection adds reload script automatically
Usage:
dev := host.NewDevServer("public", "index.html", ".", "public/app.wasm")
dev.ListenAndServe(":8080")
Closes #9
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
111
host/README.md
111
host/README.md
@@ -36,9 +36,9 @@ myapp/
|
||||
|
||||
The server serves files from the specified public directory. Any request path maps directly to files:
|
||||
|
||||
- `/` → `public/index.html`
|
||||
- `/app.wasm` → `public/app.wasm`
|
||||
- `/styles.css` → `public/styles.css`
|
||||
- `/` -> `public/index.html`
|
||||
- `/app.wasm` -> `public/app.wasm`
|
||||
- `/styles.css` -> `public/styles.css`
|
||||
|
||||
**SPA Fallback**: Unknown paths and directories fall back to `index.html`, enabling client-side routing.
|
||||
|
||||
@@ -68,28 +68,109 @@ Gzip compression is automatically applied to compressible content types when the
|
||||
|
||||
Binary assets (PNG, JPEG, etc.) are served uncompressed since they're already compressed.
|
||||
|
||||
## Development vs Production
|
||||
## Hot Reload (Development)
|
||||
|
||||
### Development
|
||||
The `DevServer` provides automatic rebuild and browser reload during development:
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
"git.flowmade.one/flowmade-one/iris/host"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Create dev server with hot reload
|
||||
dev := host.NewDevServer(
|
||||
"public", // Static files directory
|
||||
"index.html", // Index file
|
||||
".", // Source directory to watch
|
||||
"public/app.wasm", // WASM output path
|
||||
)
|
||||
|
||||
// Start watching and serving
|
||||
dev.ListenAndServe(":8080")
|
||||
}
|
||||
```
|
||||
|
||||
### How It Works
|
||||
|
||||
1. **File Watcher**: Monitors `.go` files in the source directory for changes
|
||||
2. **Auto Build**: Runs `GOOS=js GOARCH=wasm go build` when changes are detected
|
||||
3. **Browser Reload**: Injects a WebSocket client into HTML pages that triggers reload on build success
|
||||
|
||||
### Directory Structure for Development
|
||||
|
||||
```
|
||||
myapp/
|
||||
├── main.go # WASM application entry point
|
||||
├── server/
|
||||
│ └── main.go # Dev server (code above)
|
||||
└── public/
|
||||
├── index.html
|
||||
├── app.wasm # Generated by dev server
|
||||
└── wasm_exec.js
|
||||
```
|
||||
|
||||
### Workflow
|
||||
|
||||
1. Start the dev server: `go run ./server`
|
||||
2. Open `http://localhost:8080` in your browser
|
||||
3. Edit your Go source files
|
||||
4. Save - the browser automatically reloads with your changes
|
||||
|
||||
### Custom Watch Configuration
|
||||
|
||||
```go
|
||||
// Watch additional file types
|
||||
watcher := host.NewWatcher(
|
||||
".",
|
||||
onChangeCallback,
|
||||
host.WithExtensions(".go", ".html", ".css"),
|
||||
host.WithInterval(100*time.Millisecond),
|
||||
)
|
||||
```
|
||||
|
||||
### Manual Components
|
||||
|
||||
For advanced use cases, you can use the individual components:
|
||||
|
||||
```go
|
||||
// File watcher
|
||||
watcher := host.NewWatcher(".", func() {
|
||||
log.Println("Files changed")
|
||||
})
|
||||
watcher.Start()
|
||||
defer watcher.Stop()
|
||||
|
||||
// WASM builder
|
||||
builder := host.NewBuilder(".", "public/app.wasm")
|
||||
result := builder.Build()
|
||||
if result.Success {
|
||||
log.Println("Build succeeded")
|
||||
}
|
||||
|
||||
// Live reload (WebSocket notifications)
|
||||
lr := host.NewLiveReload()
|
||||
http.Handle("/__livereload", lr)
|
||||
lr.NotifyReload() // Triggers reload in all connected browsers
|
||||
```
|
||||
|
||||
## Production
|
||||
|
||||
For production, use the standard `Server` instead of `DevServer`:
|
||||
|
||||
```go
|
||||
func main() {
|
||||
server := host.New("public", "index.html")
|
||||
http.ListenAndServe(":8080", server)
|
||||
log.Fatal(http.ListenAndServe(":8080", server))
|
||||
}
|
||||
```
|
||||
|
||||
Run with:
|
||||
```bash
|
||||
go run server.go
|
||||
```
|
||||
|
||||
### Production
|
||||
|
||||
For production, compile the server and run as a binary:
|
||||
Compile and deploy:
|
||||
|
||||
```bash
|
||||
go build -o server ./server.go
|
||||
go build -o server ./server
|
||||
./server
|
||||
```
|
||||
|
||||
|
||||
Reference in New Issue
Block a user