feat: embed frontend in Go binary

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
panw
2026-03-31 16:42:54 +08:00
parent 373cb70633
commit 932b367806

24
main.go
View File

@@ -1,10 +1,14 @@
package main
import (
"embed"
"flag"
"fmt"
"io/fs"
"log"
"net/http"
"os"
"strings"
"github.com/gin-gonic/gin"
"golang.org/x/crypto/bcrypt"
@@ -15,6 +19,9 @@ import (
"gitm/internal/sync"
)
//go:embed all:web/dist
var webFS embed.FS
var (
flagAddr = flag.String("addr", "", "Listen address")
flagDataDir = flag.String("data", "", "Data directory")
@@ -90,6 +97,23 @@ func runInitMode() {
func runServer(cfg *config.Config, engine *sync.Engine) error {
gin.SetMode(gin.ReleaseMode)
r := gin.Default()
// Serve embedded frontend
distFS, err := fs.Sub(webFS, "web/dist")
if err == nil {
// Serve assets
r.StaticFS("/assets", http.FS(distFS))
// SPA fallback - serve index.html for non-API routes
r.NoRoute(func(c *gin.Context) {
if !strings.HasPrefix(c.Request.URL.Path, "/api") {
data, _ := webFS.ReadFile("web/dist/index.html")
c.Data(http.StatusOK, "text/html; charset=utf-8", data)
} else {
c.JSON(http.StatusNotFound, gin.H{"error": "Not found"})
}
})
}
api := r.Group("/api")
{
api.POST("/login", handler.HandleLogin)