如何将基于create-react-app构建的MERN栈应用部署到Heroku?
Hey there! Let's get your MERN app up and running on Heroku smoothly. I'll walk you through every step, since you've got separate frontend/backend repos plus that Node/Mongo service handling database operations. Let's dive in:
1. Restructure Your Project for Heroku
Heroku works best with a single root directory for deployment, so first we'll organize your code into a unified structure. Here's what you'll want:
your-project-root/ ├── backend/ # This is your Node/Mongo database service (rename your existing Node/Mongo project or React-backend here) │ ├── config/ │ ├── controllers/ │ ├── routes/ │ ├── server.js │ └── package.json ├── frontend/ # Your create-react-app frontend │ ├── public/ │ ├── src/ │ └── package.json └── package.json # Root-level package.json for Heroku deployment
2. Configure the Frontend
- Set up proxy for API calls: In your frontend's
package.json, add this line at the top level to avoid cross-origin issues and let Heroku handle routing automatically:
Now, instead of calling"proxy": "/api"http://localhost:8888/api/your-endpoint, just use/api/your-endpointin your frontend code—this will forward requests to the backend correctly in both development and production.
3. Tweak the Backend Settings
- Use Heroku's dynamic port: Update your
server.jsto listen on the port Heroku provides (instead of hardcoding 8888):const PORT = process.env.PORT || 8888; app.listen(PORT, () => console.log(`Server running on port ${PORT}`)); - Secure MongoDB connection: Never hardcode your MongoDB URI. Use an environment variable instead. In your backend's config file (e.g.,
config/db.js):const mongoose = require('mongoose'); const connectDB = async () => { try { await mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true }); console.log('MongoDB connected successfully!'); } catch (err) { console.error('MongoDB connection failed:', err.message); process.exit(1); } }; module.exports = connectDB; - Check backend scripts: Make sure your backend's
package.jsonhas a valid start script:
Move any production dependencies from"scripts": { "start": "node server.js", "dev": "nodemon server.js" // Optional, for local development }devDependenciestodependencies(except tools like nodemon, which are only for dev).
4. Create the Root Package.json
This tells Heroku how to build and run your app. In your project root, create a package.json with these contents:
{ "name": "your-mern-app-name", "version": "1.0.0", "scripts": { "install-all": "cd frontend && npm install && cd ../backend && npm install", "build": "cd frontend && npm run build", "start": "cd backend && npm start", "heroku-postbuild": "cd frontend && npm install && npm run build" }, "engines": { "node": ">=14.0.0", "npm": ">=6.0.0" } }
heroku-postbuild: This runs automatically during deployment to install frontend dependencies and build the production React bundle.engines: Specify the Node.js and npm versions you use locally to avoid compatibility bugs.
5. Set Up Heroku & Deploy
First, make sure you have the Heroku CLI installed and logged in:
heroku login
Then follow these steps:
- Initialize a Git repo in your project root (if you don't have one already):
git init git add . git commit -m "Prepare for Heroku deployment" - Create your Heroku app:
heroku create your-unique-app-name # Omit the name to let Heroku generate one - Set your MongoDB URI as an environment variable (use MongoDB Atlas for a cloud database—Heroku doesn't host MongoDB natively):
Replace the URI with your actual MongoDB Atlas connection string (make sure to whitelist all IPs in Atlas or use Heroku's IP range if needed).heroku config:set MONGO_URI="mongodb+srv://your-username:your-password@cluster-name.mongodb.net/your-db-name?retryWrites=true&w=majority" - Push your code to Heroku:
git push heroku main # Use "master" instead of "main" if that's your default branch - Once deployment finishes, open your app:
heroku open
6. Troubleshooting Common Issues
- If deployment fails, check the logs for details:
heroku logs --tail - Ensure all frontend API calls use relative paths (e.g.,
/api/usersinstead ofhttp://localhost:8888/api/users). - Double-check that your backend routes are prefixed with
/api(or whatever you set in the frontend proxy) to match the forwarding.
内容的提问来源于stack exchange,提问作者user5443928
相关产品推荐
相关产品推荐

