英文:
How to serve a NextJs frontend using Golang (Go) and gorilla/mux?
问题
我按照这个示例使用Golang和原生的net/http
包来提供NextJs前端单页应用程序:
import (
"embed"
"io/fs"
"log"
"net/http"
"runtime/pprof"
)
//go:embed nextjs/dist
//go:embed nextjs/dist/_next
//go:embed nextjs/dist/_next/static/chunks/pages/*.js
//go:embed nextjs/dist/_next/static/*/*.js
var nextFS embed.FS
func main() {
// 根目录为Next.js应用程序生成的`dist`文件夹。
distFS, err := fs.Sub(nextFS, "nextjs/dist")
if err != nil {
log.Fatal(err)
}
// 静态的Next.js应用程序将在`/`下提供服务。
http.Handle("/", http.FileServer(http.FS(distFS)))
// API将在`/api`下提供服务。
http.HandleFunc("/api", handleAPI)
// 在:8080上启动HTTP服务器。
log.Println("Starting HTTP server at http://localhost:8080 ...")
log.Fatal(http.ListenAndServe(":8080", nil))
}
这个代码可以正常工作。现在我想使用gorilla/mux代替原生的net/http
包。所以现在我的main
函数看起来像这样:
func main() {
// 根目录为Next.js应用程序生成的`dist`文件夹。
distFS, err := fs.Sub(nextFS, "nextjs/dist")
if err != nil {
log.Fatal(err)
}
r := mux.NewRouter()
r.Handle("/", http.FileServer(http.FS(distFS)))
srv := &http.Server{
Handler: r,
Addr: "0.0.0.0:8080",
// 最佳实践:为创建的服务器设置超时!
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
这样可以在浏览器中导航到localhost:8080
时提供index.html
文件,但页面没有样式、图片和JavaScript。
我尝试使用gorilla/mux
的说明来提供单页应用程序,但对于这个Next.js
应用程序,它找不到文件,浏览器会报连接重置错误。
为了在页面加载时使CSS、JavaScript和图片可用,你还需要做什么?
英文:
I followed this example for serving a NextJs front end single-page application using Golang and the native net/http
package:
import (
"embed"
"io/fs"
"log"
"net/http"
"runtime/pprof"
)
//go:embed nextjs/dist
//go:embed nextjs/dist/_next
//go:embed nextjs/dist/_next/static/chunks/pages/*.js
//go:embed nextjs/dist/_next/static/*/*.js
var nextFS embed.FS
func main() {
// Root at the `dist` folder generated by the Next.js app.
distFS, err := fs.Sub(nextFS, "nextjs/dist")
if err != nil {
log.Fatal(err)
}
// The static Next.js app will be served under `/`.
http.Handle("/", http.FileServer(http.FS(distFS)))
// The API will be served under `/api`.
http.HandleFunc("/api", handleAPI)
// Start HTTP server at :8080.
log.Println("Starting HTTP server at http://localhost:8080 ...")
log.Fatal(http.ListenAndServe(":8080", nil))
}
and it works. Now I want to use gorilla/mux instead of the native net/http
package. So now my main
function looks like this:
func main() {
// Root at the `dist` folder generated by the Next.js app.
distFS, err := fs.Sub(nextFS, "nextjs/dist")
if err != nil {
log.Fatal(err)
}
r := mux.NewRouter()
r.Handle("/", http.FileServer(http.FS(distFS)))
srv := &http.Server{
Handler: r,
Addr: "0.0.0.0:8080",
// Good practice: enforce timeouts for servers you create!
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
This works for serving the index.html file
when I navigate to localhost:8080
in the browser, but the page has no styling, no images, and no JavaScript.
I tried using the instructions at gorilla/mux
for serving SPAs, but for this Next.js
application, it could not find the files and the browser would error out with a connection reset error.
What else do I need to do to for the CSS, JavaScript, and images to be available when the page is loaded?
答案1
得分: 4
请注意,当添加路由时,请注意顺序:当两个路由匹配相同的路径时,先添加的路由将获胜。
r.PathPrefix("/").Handler(http.FileServer(http.FS(distFS)))
gorilla/mux将Handle
函数的第一个参数解释为模板:https://pkg.go.dev/github.com/gorilla/mux#Route.Path。
英文:
Please, try
r.PathPrefix("/").Handler(http.FileServer(http.FS(distFS)))
gorilla/mux interprets the first argument of the Handle
function as a template: https://pkg.go.dev/github.com/gorilla/mux#Route.Path.
Please, mind the order when adding routes: when two routes match the same path, the first added one wins.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论