如何在Heroku部署带Node后端的create-react-app React应用?
嘿,我帮你把这事儿捋明白——把带Node后端的React应用部署到Heroku其实没那么复杂,我给你一步步拆解,都是实战过的靠谱步骤:
部署带Node后端的React应用到Heroku完整指南
第一步:先把项目结构理清楚(如果还没调整的话)
先确保你的项目是前后端分离的结构,这样后续配置更清晰:
your-project/ ├── client/ # 把create-react-app生成的所有前端代码移到这里 │ ├── src/ │ ├── public/ │ └── package.json ├── server.js # 你的Node/Express后端入口文件 └── package.json # 根目录的package.json(Heroku会优先读取这个)
如果你的前端代码原本和后端混在一起,先把整个React项目移到client文件夹里就行。
第二步:配置根目录的package.json(核心!)
这个文件是Heroku部署的指挥中心,得加几个关键脚本和依赖:
- 先安装Express依赖:在根目录运行
npm install express - 打开根目录的
package.json,修改成这样:
{ "name": "your-app-name", "version": "1.0.0", "main": "server.js", "scripts": { "start": "node server.js", "build": "cd client && npm install && npm run build", "heroku-postbuild": "npm run build" }, "dependencies": { "express": "^4.18.2" } }
给你解释下每个脚本的作用:
start:Heroku启动应用时会自动运行这个,用来启动你的Node后端。build:先进入client文件夹,安装前端依赖,再构建React应用(生成静态的build文件夹)。heroku-postbuild:Heroku部署时会自动执行这个,帮你在服务器上完成前端构建,不用你本地把build文件夹传上去。
第三步:配置Express后端(这是你之前可能踩坑的地方)
现在修改你的server.js,重点是先处理API路由,再提供静态文件,最后处理React单页路由的回退,顺序错了就会出问题!
示例代码如下,你可以照着改:
const express = require('express'); const path = require('path'); const app = express(); // 第一步:先处理你的API路由,比如这个示例接口 app.get('/api/hello', (req, res) => { res.json({ message: '嘿,后端接口正常工作啦!' }); }); // 第二步:配置静态文件服务,指向React构建后的build文件夹 app.use(express.static(path.join(__dirname, 'client/build'))); // 第三步:处理React单页应用的路由回退——所有非API请求都返回index.html // 这一步是解决刷新页面404的关键! app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'client/build', 'index.html')); }); // 监听端口:用Heroku提供的PORT环境变量,本地测试用3001 const PORT = process.env.PORT || 3001; app.listen(PORT, () => { console.log(`服务器跑在端口 ${PORT} 上啦!`); });
划重点:
- API路由必须放在静态文件配置和
app.get('*')前面,不然API请求会被React的前端路由接管,导致接口失效。 path.join(__dirname, 'client/build')能确保不管在本地还是Heroku服务器上,都能正确找到静态文件的路径,不会出现找不到文件的错误。app.get('*')是为了适配React的单页路由——因为React的路由是前端处理的,服务器不知道这些路径,所以所有非API的请求都返回index.html,让React自己去处理路由。
第四步:调整前端的API请求路径
如果你的前端API请求写的是http://localhost:3001/api/...这种绝对路径,部署到Heroku后肯定会出错!改成相对路径就行:
// 前端请求示例,用相对路径代替绝对路径 fetch('/api/hello') .then(res => res.json()) .then(data => console.log(data));
这样不管是本地测试还是Heroku上,都会自动用当前域名的API路径,不会跨域也不会找不到接口。
第五步:本地先测一遍(避免部署后踩坑)
先在本地跑通整个流程,没问题再部署:
- 根目录运行
npm run build,确保前端能正常构建出build文件夹。 - 运行
npm start启动后端服务器。 - 访问
http://localhost:3001,看看React应用能不能正常显示,API请求能不能拿到数据。 - 刷新页面试试,确保不会出现404错误。
第六步:部署到Heroku
- 确保你已经安装了Heroku CLI,并且登录了Heroku账号。
- 根目录初始化git(如果还没的话):
git init git add . git commit -m "准备部署到Heroku" - 创建Heroku应用:
heroku create your-app-name(your-app-name可以自己改,要是重名了Heroku会自动给你分配一个)。 - 推送代码到Heroku:
git push heroku main。 - 部署完成后,运行
heroku open就能直接打开你的应用啦!
常见问题排查
- 如果部署后应用报错,先看Heroku的日志:
heroku logs --tail,日志里会有具体的错误信息,比如依赖没装、路径错了之类的,照着改就行。 - 别把
client/node_modules或者client/build提交到git,根目录的.gitignore要加上这些:node_modules/ client/node_modules/ client/build/ .env
内容的提问来源于stack exchange,提问作者user2980430
相关产品推荐
相关产品推荐

