如何使用Golang(Go)和gorilla/mux来提供Next.js前端?

huangapple go评论86阅读模式
英文:

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.

huangapple
  • 本文由 发表于 2021年12月29日 12:25:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/70515112.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定