使用Golang构建后端并与React前端结合的实践指南
使用Golang构建后端并与React前端结合的实践指南 我想将这个应用部署到 Heroku。就像使用 concurrently 将 React 与 Express/Node 后端一起部署那样,我该如何将 React 前端与 Go 后端一起部署到 Heroku 呢?是否有易于遵循的指南可以参考?
非常感谢您的帮助!
这是一个涵盖应用开发和基础设施的非常宽泛的帖子。目前,我会完全忽略基础设施方面(部署到 Heroku),专注于学习 Go 的基础知识。以下是一些很好的学习资源:
当你熟悉了基础知识,并且已经编写了几个“Hello World”级别的应用后,可以继续学习一些更侧重于 Web 开发和 React 的指南:
- https://gowebexamples.com/
- https://tutorialedge.net/projects/chat-system-in-go-and-react/
- [https://medium.com/@madhanganesh/golang-react-application-2aaf3bca92b1](https://medium.com/@madhanganesh/golang-react-application-2aaf3bca92b1)
- https://github.com/aesrael/go-postgres-jwt-react-starter
当你的 React 前端和 Go 后端能在本地运行并实现一些有趣的功能后,再开始考虑将其部署到 Heroku。
更多关于使用Golang构建后端并与React前端结合的实践指南的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
对于将React前端与Go后端一起部署到Heroku,最直接的方式是分别部署两个独立的应用,并通过环境变量配置通信。不过,如果你希望将两者部署在同一个Heroku dyno中,可以参考以下方案:
方案一:Go后端服务React静态文件(推荐)
将React应用构建为静态文件,由Go后端直接提供。这种方式部署简单,适合中小型应用。
目录结构示例:
myapp/
├── backend/
│ ├── main.go
│ └── go.mod
└── frontend/
├── build/ # React构建输出目录
├── public/
└── src/
Go后端代码示例(main.go):
package main
import (
"log"
"net/http"
"os"
)
func main() {
// 静态文件服务
fs := http.FileServer(http.Dir("./frontend/build"))
http.Handle("/", fs)
// API路由示例
http.HandleFunc("/api/data", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"message":"Hello from Go!"}`))
})
// Heroku自动分配端口
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Printf("Server starting on port %s", port)
log.Fatal(http.ListenAndServe(":"+port, nil))
}
部署步骤:
- 在React项目中运行
npm run build生成静态文件 - 将
frontend/build目录复制到Go项目目录中 - 创建Heroku应用并设置Go buildpack:
heroku create myapp
heroku buildpacks:set heroku/go
- 部署代码:
git push heroku main
方案二:使用Go代理React开发服务器(开发环境)
开发时可以使用Go代理到React开发服务器,便于热重载。
Go代理示例:
package main
import (
"log"
"net/http"
"net/http/httputil"
"net/url"
"os"
)
func main() {
// 代理到React开发服务器
reactURL, _ := url.Parse("http://localhost:3000")
proxy := httputil.NewSingleHostReverseProxy(reactURL)
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
proxy.ServeHTTP(w, r)
})
// API路由
http.HandleFunc("/api/", func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"api":"response"}`))
})
port := os.Getenv("PORT")
if port == "" {
port = "8080"
}
log.Fatal(http.ListenAndServe(":"+port, nil))
}
关键配置文件
go.mod示例:
module myapp
go 1.21
Procfile(Heroku进程文件):
web: myapp
package.json脚本示例(前端):
{
"scripts": {
"build": "react-scripts build",
"postbuild": "cp -r build ../backend/frontend/"
}
}
环境变量配置
在Heroku中设置生产环境API地址:
heroku config:set REACT_APP_API_URL=https://myapp.herokuapp.com
注意事项
- 确保Go版本在go.mod中正确指定
- React的package.json中配置正确的代理(开发时)
- 处理客户端路由:在Go中添加回退到index.html的路由
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if _, err := os.Stat("./frontend/build" + r.URL.Path); os.IsNotExist(err) {
http.ServeFile(w, r, "./frontend/build/index.html")
} else {
fs.ServeHTTP(w, r)
}
})
这种部署方式避免了Node.js环境依赖,利用Go的单一二进制特性简化部署。

