You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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('*', ...)放在后端接口路由之前,所有请求会被优先匹配到静态文件路由,导致接口无法命中。

正确的路由配置顺序

  1. 先定义所有后端API路由(如/foo、/bar);
  2. 最后再配置静态文件托管和*路由。

示例代码:

// 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 13:47:31