从零构建Node.js服务托管前端项目

发布于:2025-06-27 ⋅ 阅读:(17) ⋅ 点赞:(0)

下面是一个完整的指南,教你如何从零开始构建一个Node.js服务来托管前端项目,并代理API请求到其他服务器。

1. 项目初始化

# 创建项目目录
mkdir node-proxy-server
cd node-proxy-server

# 初始化npm项目
npm init -y

# 安装必要依赖
npm install express http-proxy-middleware compression cors morgan
npm install nodemon --save-dev

2. 基础服务器配置

创建 server.js 文件:

const express = require('express')
const path = require('path')
const { createProxyMiddleware } = require('http-proxy-middleware')
const compression = require('compression')
const cors = require('cors')
const morgan = require('morgan')

const app = express()
const PORT = process.env.PORT || 3000

// 中间件配置
app.use(compression()) // 启用gzip压缩
app.use(cors()) // 跨域支持
app.use(morgan('dev')) // 请求日志

// 静态文件服务 - 托管前端构建产物
app.use(express.static(path.join(__dirname, 'dist')))

// API代理配置
const apiProxy = createProxyMiddleware({
  target: 'http://api.your-backend.com', // 你的后端API地址
  changeOrigin: true,
  pathRewrite: {
    '^/api': '' // 移除/api前缀
  },
  onProxyReq: (proxyReq, req, res) => {
    // 可以在这里添加请求头等操作
    console.log(`代理请求: ${req.method} ${req.path} -> ${proxyReq.path}`)
  },
  onError: (err, req, res) => {
    console.error('代理错误:', err)
    res.status(500).json({ error: '代理请求失败' })
  }
})

// 应用代理中间件
app.use('/api', apiProxy)

// 处理前端路由 - 所有未匹配的请求返回index.html
app.get('*', (req, res) => {
  res.sendFile(path.join(__dirname, 'dist', 'index.html'))
})

// 启动服务器
app.listen(PORT, () => {
  console.log(`服务器运行在 http://localhost:${PORT}`)
  console.log(`代理API请求到: http://api.your-backend.com`)
})

3. 前端项目构建与部署

假设你有一个Vue/React前端项目:

  1. 构建前端项目:
# 在Vue项目中
npm run build

# 或React项目中
npm run build
  1. 将构建产物复制到Node.js项目:
# 从Vue项目
cp -R your-vue-project/dist ./node-proxy-server/

# 或从React项目
cp -R your-react-project/build ./node-proxy-server/dist

4. 环境变量配置

创建 .env 文件:

PORT=3000
API_BASE_URL=http://api.your-backend.com
NODE_ENV=production

修改 server.js 使用环境变量:

require('dotenv').config()

// 更新代理配置
const apiProxy = createProxyMiddleware({
  target: process.env.API_BASE_URL || 'http://api.your-backend.com',
  // ...其他配置不变
})

5. 高级代理配置

多API端点代理

// 用户服务
app.use('/api/user', createProxyMiddleware({
  target: 'http://user-service.your-backend.com',
  changeOrigin: true,
  pathRewrite: { '^/api/user': '' }
}))

// 订单服务
app.use('/api/order', createProxyMiddleware({
  target: 'http://order-service.your-backend.com',
  changeOrigin: true,
  pathRewrite: { '^/api/order': '' }
}))

WebSocket代理

const wsProxy = createProxyMiddleware('/ws', {
  target: 'ws://your-websocket-server.com',
  ws: true,
  changeOrigin: true,
  logLevel: 'debug'
})

app.use(wsProxy)

6. 安全增强

const helmet = require('helmet')

// 添加安全头
app.use(helmet())

// 限制请求体大小
app.use(express.json({ limit: '10kb' }))
app.use(express.urlencoded({ extended: true, limit: '10kb' }))

// 速率限制
const rateLimit = require('express-rate-limit')
const limiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15分钟
  max: 100 // 每个IP限制100个请求
})
app.use(limiter)

7. 开发与生产配置

package.json脚本

{
  "scripts": {
    "start": "node server.js",
    "dev": "nodemon server.js",
    "test": "echo \"Error: no test specified\" && exit 1"
  }
}

开发模式热重载

if (process.env.NODE_ENV === 'development') {
  const chokidar = require('chokidar')
  const watcher = chokidar.watch('./dist')
  watcher.on('ready', () => {
    watcher.on('all', () => {
      console.log('检测到前端文件变化,清除模块缓存...')
      Object.keys(require.cache).forEach(id => {
        if (id.includes('/dist/')) delete require.cache[id]
      })
    })
  })
}

8. 完整项目结构

node-proxy-server/
├── dist/                    # 前端构建产物
│   ├── index.html
│   ├── static/
│   └── ...
├── server.js                # 主服务器文件
├── .env                     # 环境变量
├── .gitignore
└── package.json

9. 部署指南

PM2生产环境部署

npm install pm2 -g
pm2 start server.js --name "node-proxy"
pm2 save
pm2 startup

Docker部署

创建 Dockerfile:

FROM node:16-alpine

WORKDIR /app

COPY package*.json ./
RUN npm install --production

COPY . .

ENV PORT=3000
ENV NODE_ENV=production

EXPOSE 3000

CMD ["node", "server.js"]

构建并运行:

docker build -t node-proxy .
docker run -d -p 3000:3000 --name node-proxy node-proxy

10. 测试与验证

  1. 启动服务器:
npm run dev
  1. 验证静态文件服务:
    访问 http://localhost:3000 应该看到你的前端应用

  2. 验证API代理:
    访问 http://localhost:3000/api/some-endpoint 应该代理到你的后端服务

  3. 验证前端路由:
    刷新非根路由(如 http://localhost:3000/about)应该正确返回index.html

常见问题解决

  1. 代理不工作:

    • 检查目标服务器是否可访问
    • 检查代理路径配置是否正确
    • 查看服务器日志中的错误信息
  2. 前端路由问题:

    • 确保所有路由都返回index.html
    • 检查前端路由模式(history vs hash)
  3. 跨域问题:

    • 确保正确配置了CORS中间件
    • 检查代理是否正确地修改了Origin头

这个Node.js代理服务器提供了完整的解决方案,包括:

  • 静态文件服务
  • API请求代理
  • 开发与生产环境支持
  • 安全增强
  • 部署选项

你可以根据实际需求进一步定制和扩展这个基础架构。


网站公告

今日签到

点亮在社区的每一天
去签到