Files
go-kata/18-embedfs-dev-prod-switch/README.md
2026-01-04 20:40:07 +01:00

55 lines
2.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Kata 18: embed.FS Dev/Prod Switch Without Handler Forks
**Target Idioms:** `embed`, `io/fs`, Build Tags, `fs.Sub`, Same Handler Code Path
**Difficulty:** 🟡 Intermediate
## 🧠 The "Why"
Embedding assets is great for production (single binary), but terrible for frontend iteration if every CSS tweak needs a rebuild.
Idiomatic Go solves this with:
- compile-time selection via build tags
- a shared `fs.FS` abstraction so handler code doesnt branch on “dev/prod”.
## 🎯 The Scenario
You run a small internal dashboard:
- Prod: ship a single binary (assets embedded).
- Dev: designers update `static/` and `templates/` live without recompiling.
## 🛠 The Challenge
Create a server that serves:
- templates from `templates/`
- static assets from `static/`
### 1. Functional Requirements
- [ ] `GET /` renders an HTML template.
- [ ] `GET /static/...` serves static files.
- [ ] Dev mode serves from disk; prod mode serves embedded.
- [ ] Handler code is identical in both modes.
### 2. The "Idiomatic" Constraints (Pass/Fail Criteria)
- [ ] **Build tags:** two files:
- `assets_dev.go` with `//go:build dev`
- `assets_prod.go` with `//go:build !dev`
- [ ] **Return `fs.FS`:** `func Assets() (templates fs.FS, static fs.FS, err error)`
- [ ] **Use `fs.Sub`:** exported FS must have *clean roots* (no `static/static/...` path bugs).
- [ ] **No runtime env checks in handlers:** mode selection must be compile-time.
- [ ] **Single `http.FileServer` setup:** no duplicated handler logic for dev vs prod.
## 🧪 Self-Correction (Test Yourself)
1. **Live Reload**
- Build with `-tags dev`.
- Modify a CSS file and refresh.
- **Pass:** change shows without rebuild.
2. **Binary Portability**
- Build without tags.
- Delete `static/` and `templates/` from disk.
- **Pass:** server still serves assets/templates.
3. **Prefix Correctness**
- Request `/static/app.css`.
- **Pass:** works in both modes (no 404 due to prefix mismatch).
## 📚 Resources
- https://pkg.go.dev/embed
- https://pkg.go.dev/io/fs
- https://pkg.go.dev/io/fs#Sub