部署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;
排查建议
检查Heroku环境变量配置:
- 确认Heroku的Config Vars中已正确设置
MONGODB_URI,值为远程MongoDB(如MongoDB Atlas)的连接字符串,本地.env文件不会被推送到Heroku,必须在Heroku后台配置。 - 若使用了其他.env密钥(如JWT_SECRET),也需同步到Heroku Config Vars。
- 确认Heroku的Config Vars中已正确设置
修复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);
调整connection.js的dotenv加载方式:
- Heroku部署时,
../.env路径可能无效,建议去掉路径参数,直接用require('dotenv').config();,依赖Heroku Config Vars提供环境变量即可。
- Heroku部署时,
配置Heroku自动构建客户端:
- 在package.json的scripts中添加postinstall脚本,确保Heroku部署时自动构建客户端:
"scripts": { "start": "node server.js", "watch": "nodemon server.js", "heroku-postbuild": "cd client && npm install && npm run build" }
- 在package.json的scripts中添加postinstall脚本,确保Heroku部署时自动构建客户端:
查看Heroku实时日志:
- 执行
heroku logs --tail查看错误详情,日志会明确显示问题根源(如数据库连接失败、语法错误、依赖缺失等)。
- 执行
指定Node/npm版本:
- 在package.json中添加engines字段,确保Heroku使用和本地一致的版本:
"engines": { "node": "16.x", "npm": "8.x" }
- 在package.json中添加engines字段,确保Heroku使用和本地一致的版本:
内容的提问来源于stack exchange,提问作者Wren Sanchez
相关产品推荐
相关产品推荐

