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

部署MERN应用至Heroku时出现应用错误,请求技术帮助

部署MERN应用到Heroku时出现应用错误(本地运行正常)

我正在完成训练营最后一项作业,时间紧迫。将MERN应用部署到Heroku时出现应用错误,尝试过以下操作但未解决:

  • 删除并重装node_modules
  • 在package.json中添加node和npm版本
  • 执行npm update
  • 重启Heroku
  • 修改PORT配置
  • 多次重写连接文件和服务文件

怀疑问题出在MongoDB或Apollo配置遗漏,或者.env密钥配置错误。


当前配置文件

package.json

{"name": "server", "version": "1.0.0", "description": "", "main": "server.js", "scripts": {"start": "node server.js", "watch": "nodemon server.js"}, "keywords": [], "author": "Wren Sanchez", "license": "ISC", "dependencies": {"bcrypt": "^5.0.0", "express": "^4.17.1", "dotenv": "^16.0.1", "graphql": "^15.5.0", "jsonwebtoken": "^8.5.1", "mongoose": "^5.9.10", "apollo-server-express": "^3.6.1", "nodemon": "^2.0.3"}, "devDependencies": {"nodemon": "^2.0.3"}}

server.js

const { ApolloServer } = require("apollo-server-express");
const express = require('express');
const path = require('path');
const db = require('./config/connection');
const { typeDefs, resolvers } = require("./schemas");
const { authMiddleware } = require('./utils/auth');
require('dotenv').config();

const app = express();
const PORT = process.env.PORT || 3001;

const server = new ApolloServer({
  typeDefs,
  resolvers,
  context: authMiddleware,
  cache: "bounded",
});

app.use(express.urlencoded({ extended: false }));
app.use(express.json());

if (process.env.NODE_ENV === 'production') {
  app.use(express.static(path.join(__dirname, '../client/build')));
}

app.get('/', (req, res) => {
  res.sendFile(path.join(__dirname, '../client/build/index.html'));
});

const startApolloServer = async (typeDefs, resolvers) => {
  await server.start();
  server.applyMiddleware({ app });

  db.once("open", () => {
    app.listen(PORT, () => {
      console.log(`API server running on port ${PORT}!`);
      console.log(
        `Use GraphQL at http://localhost:${PORT}${server.graphqlPath}`
      );
    });
  });

startApolloServer(typeDefs, resolvers);
}

connection.js

const mongoose = require('mongoose');
require('dotenv').config({ path: '../.env' });

mongoose.connect(process.env.MONGODB_URI || 'mongodb://localhost:27017/googlebooks', {
  useNewUrlParser: true,
  useUnifiedTopology: true,
});

module.exports = mongoose.connection;

排查建议

  1. 检查Heroku环境变量配置:

    • 确认Heroku的Config Vars中已正确设置MONGODB_URI,值为远程MongoDB(如MongoDB Atlas)的连接字符串,本地.env文件不会被推送到Heroku,必须在Heroku后台配置。
    • 若使用了其他.env密钥(如JWT_SECRET),也需同步到Heroku Config Vars。
  2. 修复server.js语法错误:

    • startApolloServer函数存在括号闭合缺失,导致语法错误,修正后代码如下:
      const startApolloServer = async (typeDefs, resolvers) => {
        await server.start();
        server.applyMiddleware({ app });
      
        db.once("open", () => {
          app.listen(PORT, () => {
            console.log(`API server running on port ${PORT}!`);
            console.log(
              `Use GraphQL at http://localhost:${PORT}${server.graphqlPath}`
            );
          });
        });
      }; // 补充缺失的函数闭合括号
      
      startApolloServer(typeDefs, resolvers);
      
  3. 调整connection.js的dotenv加载方式:

    • Heroku部署时,../.env路径可能无效,建议去掉路径参数,直接用require('dotenv').config();,依赖Heroku Config Vars提供环境变量即可。
  4. 配置Heroku自动构建客户端:

    • 在package.json的scripts中添加postinstall脚本,确保Heroku部署时自动构建客户端:
      "scripts": {
        "start": "node server.js",
        "watch": "nodemon server.js",
        "heroku-postbuild": "cd client && npm install && npm run build"
      }
      
  5. 查看Heroku实时日志:

    • 执行heroku logs --tail查看错误详情,日志会明确显示问题根源(如数据库连接失败、语法错误、依赖缺失等)。
  6. 指定Node/npm版本:

    • 在package.json中添加engines字段,确保Heroku使用和本地一致的版本:
      "engines": {
        "node": "16.x",
        "npm": "8.x"
      }
      

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 18:39:28