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

如何将自建React+Express项目部署到Heroku?

Hey there! Congrats on getting your React + Express setup working locally with webpack --watch—that's a solid start. Let's walk through how to get this deployed to Heroku step by step, since their platform has a few specific requirements you'll need to account for as a first-time full-stack deployer.


Step 1: Tweak Your package.json for Heroku Compatibility

Heroku relies on your package.json to know how to build and run your app. Here's what you need to adjust:

1.1 Update Scripts

Your local start script uses webpack --watch for development, but production doesn't need live reloading. Replace it with separate dev and production scripts:

"scripts": {
  "dev": "webpack --watch & node server.js", // Keep this for local development
  "build": "webpack --mode production", // Heroku will run this to build your React bundle
  "start": "node server.js" // Heroku uses this to start your Express server
}

1.2 Specify Node.js Version

Add an engines field to avoid version mismatches between your local setup and Heroku:

"engines": {
  "node": ">=16.x",
  "npm": ">=8.x"
}

Use the same Node/npm version you're running locally (check with node -v and npm -v).

1.3 Ensure Dependencies Are Correct

Make sure all build tools (like webpack, babel-loader, etc.) are in devDependencies—Heroku will install them during the build phase, then discard them to save space. If you run into build errors later, you can temporarily move them to dependencies, but devDependencies is the right place for tools only needed during development/build.


Step 2: Configure Express to Serve React's Production Build

Heroku will run npm run build to generate your optimized React bundle (usually in a dist folder, depending on your webpack config). Your Express server needs to serve these static files and handle SPA routing:

2.1 Serve Static Files

Add this to your server file (e.g., server.js or server/index.js):

const path = require('path');
const express = require('express');
const app = express();

// Serve React's static files from the dist folder
app.use(express.static(path.join(__dirname, 'dist')));
// If your server code is in a subfolder (like /server), use ../dist instead:
// app.use(express.static(path.join(__dirname, '../dist')));

2.2 Handle SPA Routing

For single-page apps, any non-API request should return React's index.html to avoid 404s when users refresh:

// Place this AFTER all your API routes
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist', 'index.html'));
  // Adjust path if server is in a subfolder: path.join(__dirname, '../dist', 'index.html')
});

2.3 Use Heroku's Dynamic Port

Heroku assigns a random port to your app via the PORT environment variable—never hardcode a port like 3000:

const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
  console.log(`Server running on port ${PORT}`);
});

Step 3: Optimize webpack.config.js for Production

Make sure your webpack config is set up to generate a production-ready bundle:

3.1 Set Output Path and Filenames

Ensure your build outputs to a consistent folder (like dist) with hashed filenames for caching:

const path = require('path');

module.exports = (env, argv) => {
  const isProduction = argv.mode === 'production';

  return {
    entry: './src/index.js', // Your React entry point
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: isProduction ? '[name].[contenthash].js' : '[name].js',
      clean: true, // Empty the dist folder before each build
    },
    // ... rest of your config
  };
};

3.2 Adjust Devtool and Plugins

  • For production, use devtool: 'source-map' (or false if you don't need source maps) instead of inline dev tools.
  • Use MiniCssExtractPlugin to extract CSS into separate files (instead of style-loader for development):
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');

// Inside your module.rules for CSS:
{
  test: /\.css$/,
  use: [isProduction ? MiniCssExtractPlugin.loader : 'style-loader', 'css-loader'],
}

// Inside plugins array:
plugins: [
  new HtmlWebpackPlugin({ template: './public/index.html' }),
  isProduction && new MiniCssExtractPlugin({ filename: '[name].[contenthash].css' }),
].filter(Boolean) // Only include the CSS plugin in production

Step 4: Deploy to Heroku

Now you're ready to push your code live:

  1. Initialize Git (if you haven't already):

    git init
    git add .
    git commit -m "Prepare app for Heroku deployment"
    
  2. Install Heroku CLI (if you don't have it), then log in:

    heroku login
    
  3. Create a Heroku app:

    heroku create your-app-name # Replace with a unique name, or leave blank for a random one
    
  4. Deploy your code:

    git push heroku main
    
  5. Open your live app:

    heroku open
    

Troubleshooting Common Issues
  • Build fails: Check Heroku's logs with heroku logs --tail to see exactly what's breaking. Common fixes: missing dependencies, incorrect webpack config paths, or Node version mismatches.
  • 404 on page refresh: Double-check your SPA routing code in Express—make sure app.get('*') is placed after all your API routes.
  • Static files not loading: Verify the path to your dist folder in Express is correct (use path.resolve to avoid relative path bugs).

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 09:01:31