feat: 将前端 dist 嵌入 Go 后端实现单文件部署
This commit is contained in:
56
backend/internal/static/static.go
Normal file
56
backend/internal/static/static.go
Normal file
@@ -0,0 +1,56 @@
|
||||
package static
|
||||
|
||||
import (
|
||||
"embed"
|
||||
"io/fs"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
//go:embed dist/*
|
||||
var StaticFiles embed.FS
|
||||
|
||||
// Handler 返回静态文件处理器
|
||||
// 用于服务嵌入的前端静态文件
|
||||
func Handler() http.Handler {
|
||||
// 提取 dist 子目录
|
||||
distFS, err := fs.Sub(StaticFiles, "dist")
|
||||
if err != nil {
|
||||
// 如果 dist 目录不存在,返回空处理器
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Static files not available", http.StatusNotFound)
|
||||
})
|
||||
}
|
||||
|
||||
fileServer := http.FileServer(http.FS(distFS))
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// 对于 API 路径,不处理
|
||||
if strings.HasPrefix(r.URL.Path, "/api/") {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// 尝试服务静态文件
|
||||
// 对于 SPA,如果文件不存在,返回 index.html
|
||||
path := r.URL.Path
|
||||
if path == "/" {
|
||||
path = "/index.html"
|
||||
}
|
||||
|
||||
// 检查文件是否存在
|
||||
_, err := fs.Stat(distFS, strings.TrimPrefix(path, "/"))
|
||||
if err != nil {
|
||||
// 文件不存在,返回 index.html(支持 SPA 路由)
|
||||
r.URL.Path = "/"
|
||||
}
|
||||
|
||||
fileServer.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
|
||||
// IsAvailable 检查静态文件是否可用
|
||||
func IsAvailable() bool {
|
||||
_, err := fs.Sub(StaticFiles, "dist")
|
||||
return err == nil
|
||||
}
|
||||
Reference in New Issue
Block a user