使用Golang构建后端并与React前端结合的实践指南

使用Golang构建后端并与React前端结合的实践指南 我想将这个应用部署到 Heroku。就像使用 concurrently 将 React 与 Express/Node 后端一起部署那样,我该如何将 React 前端与 Go 后端一起部署到 Heroku 呢?是否有易于遵循的指南可以参考?

非常感谢您的帮助!

2 回复

这是一个涵盖应用开发和基础设施的非常宽泛的帖子。目前,我会完全忽略基础设施方面(部署到 Heroku),专注于学习 Go 的基础知识。以下是一些很好的学习资源:

当你熟悉了基础知识,并且已经编写了几个“Hello World”级别的应用后,可以继续学习一些更侧重于 Web 开发和 React 的指南:

当你的 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))
}

部署步骤:

  1. 在React项目中运行 npm run build 生成静态文件
  2. frontend/build 目录复制到Go项目目录中
  3. 创建Heroku应用并设置Go buildpack:
heroku create myapp
heroku buildpacks:set heroku/go
  1. 部署代码:
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

注意事项

  1. 确保Go版本在go.mod中正确指定
  2. React的package.json中配置正确的代理(开发时)
  3. 处理客户端路由:在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的单一二进制特性简化部署。

回到顶部