gorilla/mux
gospa
vue create gospa
cd gospa
yarn serve
http://localhost:8080/
接下来,我们通过后端实现 HTTP 服务器来托管前端应用和资源访问。
gospaserver.go
package main
import (
"github.com/gorilla/mux"
"log"
"net/http"
"os"
"path/filepath"
"time"
)
// spaHandler 实现了 http.Handler 接口,所以可以用来处理 HTTP 请求
// 其中 staticPath 用于定义前端静态资源目录(包含js、css 文件)
// indexPath 用于定义入口视图模板文件,通常是 index.html
type spaHandler struct {
staticPath string
indexPath string
}
// 处理 SPA 应用请求(主要是首次访问时入口 HTML 文档和相关静态资源文件,暂不涉及 API 接口)
func (h spaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// 获取 URL 路径的绝对路径
path, err := filepath.Abs(r.URL.Path)
if err != nil {
// 如果获取失败,返回 400 响应
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
// 在 URL 路径前加上静态资源根目录
path = filepath.Join(h.staticPath, path)
// 检查对应资源文件是否存在
_, err = os.Stat(path)
if os.IsNotExist(err) {
// 文件不存在返回入口 HTML 文档内容作为响应
http.ServeFile(w, r, filepath.Join(h.staticPath, h.indexPath))
return
} else if err != nil {
// 如果期间报错,返回 500 响应
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
// 一切顺利,则使用 http.FileServer 处理静态资源请求
http.FileServer(http.Dir(h.staticPath)).ServeHTTP(w, r)
}
func main() {
router := mux.NewRouter()
spa := spaHandler{staticPath: "dist", indexPath: "index.html"}
router.PathPrefix("/").Handler(spa)
srv := &http.Server{
Handler: router,
Addr: "127.0.0.1:8000",
// 最佳实践:为服务器读写设置超时时间
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
具体的业务逻辑都已经写在注释里了。
接下来,我们通过 Go Module 管理 Go 依赖:
go mod init gospa
go mod tidy
然后启动这个基于 Go 实现的 HTTP 服务器:
go run server.go
gospa/src/App.VueHelloWorldmsg
<HelloWorld msg="Welcome to Your Vue.js + Golang SPA App"/>
gospayarn builddist
第一个红框区域对应的目录就是编译后的前端静态资源和 HTML 视图模板所在目录。
http://127.0.0.1:8000
msg