MERN全栈电商应用部署Heroku遇问题求助
MERN电商网站Heroku部署及接口404问题解决方案
一、能否在单个Heroku应用部署?
完全可以,无需拆分两个应用。通过Node后端托管React静态文件是MERN栈部署的标准方案,你的目录结构完全支持这种模式。
部署失败排查
结合你的场景,部署失败大概率是以下原因:
- 依赖未完整安装:Heroku默认仅安装根目录
package.json的依赖,但React项目的依赖也需要在部署阶段安装并完成构建。修改根目录package.json,添加heroku-postbuild脚本:
注意:"scripts": { "start": "node server.js", "heroku-postbuild": "cd react && npm install && npm run build" }start脚本只需启动后端服务,构建步骤放在heroku-postbuild中(Heroku部署时会自动执行),无需每次启动都重复构建。 - 环境变量未配置:
.env文件不会被提交到Git,需在Heroku应用设置的「Config Vars」中配置MongoDB连接字符串等环境变量。 - 端口硬编码:Node后端必须使用Heroku提供的
PORT环境变量,不能固定端口:const port = process.env.PORT || 5000; app.listen(port, () => console.log(`Server running on port ${port}`));
二、后端接口返回404的解决方案
出现这个问题的核心原因是Express路由顺序错误:如果把静态文件托管的app.get('*', ...)放在后端接口路由之前,所有请求会被优先匹配到静态文件路由,导致接口无法命中。
正确的路由配置顺序
- 先定义所有后端API路由(如
/foo、/bar); - 最后再配置静态文件托管和
*路由。
示例代码:
// 1. 先注册所有后端API路由 app.get('/foo', (req, res) => { res.json({ data: 'Foo接口返回内容' }); }); app.get('/bar', (req, res) => { res.json({ data: 'Bar接口返回内容' }); }); // 2. 最后托管React静态文件 const path = require('path'); app.use(express.static(path.join(__dirname, 'react/build'))); // 匹配所有非API路由,返回React的index.html app.get('*', (req, res) => { res.sendFile(path.join(__dirname, 'react/build', 'index.html')); });
额外注意
- React前端调用后端接口时,直接使用相对路径(如
/foo)即可,无需本地代理路径,部署后前后端共享同一域名; - 本地开发用的
proxy配置仅在本地生效,部署到Heroku后可删除或保留,不影响线上运行。
内容的提问来源于stack exchange,提问作者Mario
相关产品推荐
相关产品推荐

