Reputation: 2322
I have a go project which uses VueJS
to provide web interface. While build the project, I first use npm run build
to compile the frontend code, which is generated under gui/dist
of my project dir. Then I use this code to serve the static contents:
//go:embed gui/dist/*
var dist embed.FS
gui := http.FileServer(http.FS(dist))
http.Handle("/", gui)
http.HandleFunc("/api/", func(w http.ResponseWriter, r *http.Request) {
msg := fmt.Sprintf("TODO: %s", r.URL)
http.Error(w, msg, http.StatusNotImplemented)
})
svr := http.Server{
Addr: fmt.Sprintf(":%v", cf.HTTPPort),
ReadTimeout: time.Minute,
WriteTimeout: time.Minute,
}
assert(svr.ListenAndServe())
The problem is, when open the site in browser, it shows me a browse file interface, i.e. starting with gui, and then into dist, then shows the index.html
file, which is a blank page, because it requires files such as /css/...
, while the go web server serves it at /gui/dist/css/...
.
I tried to use http.StripPrefix()
but apparently it is not intended to handle this situation, or I didn't use it correctly:
http.Handle("/", http.StripPrefix("/gui/dist", gui))
which generated a 404 page not found
.
Upvotes: 15
Views: 5657
Reputation: 16253
You may use fs.Sub(dist, "gui/dist")
(docs), try it:
package main
import (
"embed"
"fmt"
"io/fs"
"log"
"net/http"
)
func main() {
http.Handle("/", http.FileServer(getFileSystem()))
http.HandleFunc("/api/", api)
err := http.ListenAndServe(":8080", nil)
if err != nil {
log.Fatal(err)
}
}
func getFileSystem() http.FileSystem {
fsys, err := fs.Sub(dist, "gui/dist")
if err != nil {
log.Fatal(err)
}
return http.FS(fsys)
}
func api(w http.ResponseWriter, r *http.Request) {
msg := fmt.Sprintf("TODO: %s", r.URL)
http.Error(w, msg, http.StatusNotImplemented)
}
//go:embed gui/dist/*
var dist embed.FS
Upvotes: 22