webpack 5 websocket 热更新的问题

830 阅读1分钟

起因

有时候前端开发需要使用域名访问到本地的项目,一般我们的操作是修改 Host ,然后通过 nginx 反向代理到本地运行的项目。然而使用最新 vue cli 创建的项目内置的是webpack 5,webpack 5实现热更新是使用了 websocket。当我们通过 https 协议的域名访问项目时,websocket 就会连接不上,导致热更新失败。

比如:我们的项目通过 dev.danny.com 访问本地运行在 8088 端口的项目

复现

使用 https 访问,就会报错

image.png

使用域名访问项目,websocket的请求连接也会变成域名,像是这样:

image.png

一般前端使用nginx只是简单代理项目,如下配置

location / {
      charset      utf-8;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      proxy_pass   https://127.0.0.1:8088;
 }

解决

  1. 经过一通折腾,发现websocket地址是带有端口号的,我们是同事443访问页面不需要带端口号,所以在nginx 层需要修改
      # WebSocket support
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
      # 转发socket协议需要指定到端口号
      proxy_set_header Host $host:$server_port;

      # Additional headers for WebSocket
      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_set_header X-Forwarded-Host $host;
      proxy_set_header X-Forwarded-Port $server_port;
  1. 项目本地的 vue.config.js 中也需要开启https,并使用和nginx相同的证书
devServer: {
    port: 8088,
    headers: {
      'Access-Control-Allow-Origin': '*'
    },
    allowedHosts: [
      'dev.danny.com'
    ],
    https:{
      key: fs.readFileSync(resolvePath('cert/*.danny.com-key.pem')),
      cert: fs.readFileSync(resolvePath('cert/*.danny.com.pem')),
    },
    client: {
      logging: 'info',
      overlay: true,
      webSocketURL: {
        hostname: 'dev.danny.com',
        pathname: '/ws',
        protocol: 'https'
      }
    }
  }

结果

image.png

image.png

websocket 可以正常收到热更新推送。

本文目的是记录一下问题。 对于nginx部分的原理还不是很清楚。欢迎交流👏🏻