在一台服务器上同时部署Vue前端和Node.js后端有多种方式,我来介绍几种主流的方案:
方案一:前后端分离部署(推荐)
1. 前端构建
# 在Vue项目根目录
npm run build
# 生成dist目录
2. 后端代码结构
project/
├── backend/
│ ├── server.js
│ ├── routes/
│ └── package.json
├── frontend/
│ ├── dist/ (构建后的文件)
│ └── src/
└── package.json
3. Node.js后端配置
// backend/server.js
const express = require('express');
const path = require('path');
const app = express();
// 静态文件服务
app.use(express.static(path.join(__dirname, '../frontend/dist')));
// API路由
app.use('/api', require('./routes/api'));
// 所有其他请求返回index.html
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, '../frontend/dist/index.html'));
});
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`Server running on port ${PORT}`);
});
方案二:使用Nginx反向
Nginx配置
server {
listen 80;
server_name your-domain.com;
# 前端静态文件
location / {
root /var/www/frontend/dist;
try_files $uri $uri/ /index.html;
}
# API请求到Node.js
location /api/ {
proxy_pass http://localhost:3001;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}
Node.js后端(监听3001端口)
const express = require('express');
const app = express();
app.use(express.json());
// API路由
app.get('/api/users', (req, res) => {
res.json({ users: [] });
});
app.listen(3001, () => {
console.log('API server running on port 3001');
});
方案三:一体化部署
修改Vue配置
// vue.config.js
module.exports = {
// 构建输出目录
outputDir: 'dist',
// 开发服务器
devServer: {
proxy: {
'/api': {
target: 'http://localhost:3000',
changeOrigin: true,
}
}
}
}
一体化Node.js服务器
const express = require('express');
const { createProxyMiddleware } = require('http-proxy-middleware');
const path = require('path');
const app = express();
// 生产环境:提供静态文件
if (process.env.NODE_ENV === 'production') {
app.use(express.static(path.join(__dirname, 'dist')));
// API路由
app.use('/api', require('./routes/api'));
// SPA路由
app.get('*', (req, res) => {
res.sendFile(path.join(__dirname, 'dist', 'index.html'));
});
}
// 开发环境:API请求
else {
app.use('/api', createProxyMiddleware({
target: 'http://localhost:5000',
changeOrigin: true,
}));
}
app.listen(process.env.PORT || 3000);
部署脚本示例
部署脚本 (deploy.sh)
#!/bin/bash
echo "开始部署..."
# 进入项目目录
cd /path/to/your/project
# 拉取最新代码
git pull origin main
# 安装依赖
npm install
# 构建前端
cd frontend
npm run build
cd ..
# 重启服务
pm2 restart app-name
echo "部署完成!"
PM2进程管理
// ecosystem.config.js
module.exports = {
apps: [
{
name: 'my-app',
script: './backend/server.js',
instances: 1,
autorestart: true,
watch: false,
max_memory_restart: '1G',
env: {
NODE_ENV: 'development'
},
env_production: {
NODE_ENV: 'production'
}
}
]
};
环境变量配置
.env 文件
# 开发环境
NODE_ENV=development
PORT=3000
DB_HOST=localhost
DB_PORT=27017
# 生产环境
NODE_ENV=production
PORT=80
DB_HOST=mongodb://db-server:27017
安全建议
-
使用HTTPS:
# Nginx HTTPS配置 server { listen 443 ssl; ssl_certificate /path/to/cert.pem; ssl_certificate_key /path/to/key.pem; } -
CORS配置:
const cors = require('cors'); app.use(cors({ origin: ['https://yourdomain.com'], credentials: true })); -
错误处理:
app.use((err, req, res, next) => { console.error(err.stack); res.status(500).json({ error: 'Something went wrong!' }); });
推荐方案
对于生产环境,我推荐方案二(Nginx + Node.js),因为:
- ✅ 更好的性能优化
- ✅ 易于扩展
- ✅ 更好的安全控制
- ✅ 支持负载均衡
- ✅ 静态文件缓存
选择哪种方案取决于你的具体需求、团队技能和运维能力。
CLOUD技术笔记