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

在Heroku部署React应用时遇'Could not find a required file. Name: index.html'错误

解决Heroku部署React+Express应用时找不到index.html的问题

嘿,刚接触React和部署确实容易踩这些坑,别着急,咱们一步步把问题搞定!你遇到的核心问题是构建脚本的执行路径不对,再加上server.js里的静态文件配置有误,导致Heroku找不到index.html,生产环境也没法正确提供前端资源。

1. 先修正package.json的脚本配置

你的根目录package.json里的build脚本直接在根目录跑react-scripts build,但React项目的public和src都在client子文件夹里啊!根目录根本没有这些文件,难怪会报错找不到index.html。另外,Heroku需要明确你的Node和npm版本,得把版本信息放到engines字段里(你之前直接写在根节点是无效的)。

修正后的package.json关键部分:

"name": "mern-auth",
"version": "1.0.0",
"homepage": "./",
"description": "Mern Auth Example",
"main": "server.js",
"engines": {
  "node": "v12.13.1",
  "npm": "6.13.4"
},
"scripts": {
  "client-install": "npm install --prefix client",
  "build": "cd client && npm run build", // 进入client目录再执行构建
  "start": "node server.js",
  "server": "nodemon server.js",
  "client": "npm start --prefix client",
  "dev": "concurrently \"npm run server\" \"npm run client\"",
  "heroku-postbuild": "npm run client-install && npm run build" // 让Heroku自动安装client依赖并构建
}

加个heroku-postbuild脚本很重要,这样Heroku部署时会自动安装client的依赖,不用手动处理。

2. 修复server.js的静态文件服务和路由 fallback

生产环境下,Express要提供的是React构建好的静态文件(也就是client/build里的内容),不是直接访问client/public。而且路由 fallback 要指向build文件夹里的index.html,不是public里的原始文件。另外,你之前漏了导入express,这会导致服务器启动失败哦!

修正后的server.js核心代码:

// 先补上express的导入!
const express = require('express');
const mongoose = require("mongoose");
const bodyParser = require("body-parser");
const passport = require("passport");
const path = require('path');
const users = require("./routes/api/users");
const plaid = require("./routes/api/plaid");
const morgan = require("morgan");

const app = express();

// Bodyparser和日志中间件
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.use(morgan("tiny"));

// API接口
app.get("/api/message", async (req, res, next) => {
  try {
    res.status(201).json({ message: "HELLOOOOO FROM EXPRESS" });
  } catch (err) {
    next(err);
  }
});

// 生产环境静态文件配置
if (process.env.NODE_ENV === "production") {
  // 指向client/build文件夹
  const buildPath = path.resolve(__dirname, 'client', 'build');
  app.use(express.static(buildPath));

  // 所有非API请求都返回React的index.html(解决单页应用路由问题)
  app.get('*', (req, res) => {
    res.sendFile(path.join(buildPath, 'index.html'));
  });
}

// Passport配置
app.use(passport.initialize());
require("./config/passport")(passport);

// 挂载API路由
app.use("/api/users", users);
app.use("/api/plaid", plaid);

// 连接MongoDB(放到服务器启动前)
const db = require("./config/keys").mongoURI;
mongoose.connect(db, { useNewUrlParser: true })
  .then(() => console.log("MongoDB successfully connected"))
  .catch(err => console.log(err));

// 启动服务器
const port = process.env.PORT || 5000;
app.listen(port, () => {
  console.log(`Server is up on port ${port}!`);
});

3. 最后做个本地测试再部署

先在本地跑一遍生产环境流程:

  1. 运行npm run build,看看client文件夹下有没有生成build文件夹
  2. 运行npm start,访问http://localhost:5000,确认应用能正常加载
  3. 没问题的话,就可以推代码到Heroku了

这样调整后,Heroku就能正确构建前端资源,服务器也能正确提供静态文件,应该就能解决你的问题啦!

内容的提问来源于stack exchange,提问作者wharfchillin

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 11:32:45