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

如何构建单package.json与node_modules的React+Express前后端项目

React + Express Monorepo with Single package.json

Great question! This streamlined setup with a single package.json and shared node_modules is perfect for keeping your project organized without redundant configs. Here's my battle-tested implementation:

Step 1: Initialize Project Structure

First, set up your base folders and root package.json:

mkdir react-express-monorepo
cd react-express-monorepo
npm init -y
mkdir -p client/{public,src} server

Step 2: Install All Dependencies

We'll bundle both React (via react-scripts) and Express dependencies in the root package.json:

# Core dependencies
npm install express react react-dom react-scripts cors

# Dev tools (for concurrent dev servers and backend hot-reload)
npm install --save-dev concurrently nodemon react-app-rewired

Step 3: Set Up React Frontend

Since we're skipping the standalone create-react-app package.json, we'll manually add the core React files:

  1. client/public/index.html (copy this standard CRA template):
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta name="description" content="React + Express Monorepo" />
    <title>React + Express App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>
  1. client/src/index.js:
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);
  1. client/src/App.js:
import React, { useEffect, useState } from 'react';
import './App.css';

function App() {
  const [message, setMessage] = useState('');

  useEffect(() => {
    // Fetch data from Express backend
    fetch('http://localhost:5000/api/hello')
      .then(res => res.json())
      .then(data => setMessage(data.message));
  }, []);

  return (
    <div className="App">
      <header className="App-header">
        <h1>React + Express Monorepo</h1>
        {message && <p>{message}</p>}
      </header>
    </div>
  );
}

export default App;
  1. Add CSS files: Copy the default index.css and App.css from a standard CRA setup into client/src/.

Step 4: Configure React Build Output

By default, react-scripts builds to a root build folder. We'll use react-app-rewired to redirect builds to client/build without ejecting:

Create a root config-overrides.js file:

const path = require('path');

module.exports = {
  paths: (paths) => {
    paths.appBuild = path.resolve(__dirname, 'client/build');
    return paths;
  },
};

Step 5: Set Up Express Backend

Create server/server.js with this basic setup (includes static file serving for production and API routes):

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

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

// Enable CORS for dev environment
app.use(cors());

// Parse JSON requests
app.use(express.json());

// Example API route
app.get('/api/hello', (req, res) => {
  res.json({ message: 'Hello from your Express backend!' });
});

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

  // Catch-all route to serve React app
  app.get('*', (req, res) => {
    res.sendFile(path.join(__dirname, '../client/build/index.html'));
  });
}

app.listen(PORT, () => {
  console.log(`Server running on port ${PORT} 🚀`);
});

Step 6: Configure Root package.json Scripts

Update your root package.json scripts to handle development, production, and builds seamlessly:

"scripts": {
  "start": "NODE_ENV=production node server/server.js",
  "dev": "concurrently \"npm run server\" \"npm run client\"",
  "server": "nodemon server/server.js",
  "client": "react-app-rewired start",
  "build": "react-app-rewired build",
  "test": "react-app-rewired test",
  "eject": "react-scripts eject"
}

Script Breakdown:

  • npm run dev: Starts both the Express backend (with nodemon hot-reload) and React dev server simultaneously.
  • npm run server: Runs only the Express backend with hot-reload.
  • npm run client: Runs only the React dev server.
  • npm run build: Builds the React app to client/build.
  • npm start: Runs the production server (serves the built React app + API).

Step 7: Set Up .gitignore

Create a root .gitignore file to exclude unnecessary files:

node_modules/
client/build/
.env
npm-debug.log*
yarn-debug.log*
yarn-error.log*
.DS_Store
.vscode/
.idea/

Key Tips for Maintenance

  • Dependency Management: All packages are installed at the root, so npm install handles everything—no need to run installs in subfolders.
  • Environment Variables: Use a root .env file for backend variables, and prefix React variables with REACT_APP_ (react-scripts will pick them up automatically).
  • Testing: Keep test files alongside your components/backend code (e.g., client/src/App.test.js, server/server.test.js)—react-app-rewired test will handle React tests, and you can add a separate test script for backend with Jest if needed.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 04:21:16