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

生产环境下Vite WebSocket连接丢失问题求助

解决Vite SSR Docker环境下WebSocket连接失败问题

核心问题分析

你的报错源于生产/非dev:client模式下,客户端代码残留了Vite HMR的连接逻辑,导致浏览器反复尝试连接WebSocket端口24678,但服务器端的网络配置或构建流程未匹配该需求;或是dev:server模式下HMR的客户端连接地址配置错误。


解决方案1:生产环境彻底禁用HMR

生产环境(serve命令)不需要HMR,需确保构建的客户端代码完全剔除HMR相关逻辑:

  1. 修改Vite配置,按环境控制HMR开关
    更新vite.config.ts,仅在非生产环境启用HMR:

    import { defineConfig } from "vite";
    import react from "@vitejs/plugin-react";
    
    const isProd = process.env.NODE_ENV === "production";
    const PORT = process.env.VITE_PORT ? parseInt(process.env.VITE_PORT) : 3000;
    
    export default defineConfig({
      plugins: [react()],
      server: {
        port: PORT,
        watch: {
          usePolling: true,
        },
        hmr: {
          enabled: !isProd, // 生产环境直接禁用HMR
          host: "0.0.0.0", // 允许容器外访问HMR(仅开发环境生效)
        },
      },
      build: {
        minify: false,
      },
      define: {
        "import.meta.env": JSON.stringify(process.env),
      },
    });
    
  2. 构建时强制设置生产环境变量
    修改package.json的build:client脚本,添加环境变量确保构建产物为生产版本:

    "build:client": "cross-env NODE_ENV=production vite build --outDir dist/client --ssrManifest",
    

    此操作会让Vite自动剔除HMR相关代码,避免浏览器发起无效的WebSocket连接。


解决方案2:dev:server模式下正确配置HMR连接

如果需要在dev:server模式下保留HMR功能,需确保客户端能正确连接容器内的HMR服务:

  1. 统一HMR端口到应用端口
    在vite.config.ts的server.hmr中设置clientPort为应用端口(3000),无需额外开放24678端口:

    hmr: {
      enabled: true,
      host: "0.0.0.0",
      clientPort: 3000, // 和应用端口一致,减少端口配置成本
    },
    
  2. Nginx反向代理WebSocket请求
    更新Nginx配置,确保WebSocket升级请求被正确代理到容器:

    server {
      listen 80;
      server_name example;
    
      location / {
        proxy_pass http://localhost:3000;
        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;
    
        # 处理WebSocket协议升级
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
      }
    }
    
  3. 检查服务器网络配置

    • 确认Docker容器已映射3000端口:ports: ["3000:3000"]
    • 防火墙开放3000端口:sudo ufw allow 3000
    • 用netstat -tulpn | grep 3000确认端口未被其他进程占用

解决方案3:SSR渲染时动态注入HMR脚本

如果是SSR应用,需确保仅在开发环境注入Vite客户端脚本:
修改entryServer.tsx,根据环境判断是否添加HMR相关脚本:

import { renderToString } from 'react-dom/server';
import App from './App';

export async function render() {
  const appHtml = renderToString(<App />);
  let viteScript = '';

  // 仅开发环境注入Vite客户端脚本
  if (process.env.NODE_ENV !== 'production') {
    const vite = await import('vite');
    const devServer = await vite.createServer({
      server: { middlewareMode: true },
    });
    viteScript = `<script type="module" src="${devServer.resolvedUrls.local[0]}@vite/client"></script>`;
  }

  return `
    <html>
      <head>
        <title>Your App</title>
      </head>
      <body>
        <div id="root">${appHtml}</div>
        ${viteScript}
      </body>
    </html>
  `;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 12:05:07