VitePress dev 反代到 Nginx 后 HMR 不工作(WebSocket)
问题
把 vitepress dev 放在内网跑(例如 0.0.0.0:11434),对外通过 Nginx 反代(例如 https://ai.icetk.top)。
现象:
- 页面能打开,但修改
docs/**/*.md后浏览器不热更新(HMR 不生效) - 控制台看到 WebSocket 连接失败,常见报错:
WebSocket connection to 'wss://xxx' failednet::ERR_CONNECTION_RESET- 或者一直 pending
环境
- VitePress:
2.0.0-alpha.17 - 访问方式:
https://<domain>(Nginx 反代) - Dev Server:
vitepress dev docs --host 0.0.0.0 --port 11434
原因(定位过程)
HMR 依赖 WebSocket。
Nginx 默认反代只处理普通 HTTP 请求,如果未正确转发 Upgrade/Connection 头、未启用 HTTP/1.1、或 WebSocket location 被其它规则覆盖,就会导致 WS 握手失败,从而 HMR 不生效。
解决方案
方案 A:Nginx 反代正确开启 WebSocket
推荐用 map 处理 Connection:
nginx
map $http_upgrade $connection_upgrade {
default upgrade;
'' close;
}然后在你的 server 块里:
nginx
server {
listen 443 ssl http2;
server_name ai.icetk.top;
# ssl_certificate ...
# ssl_certificate_key ...
location / {
proxy_pass http://127.0.0.1:11434;
proxy_http_version 1.1;
# 关键:WebSocket
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection $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;
}
}方案 B:让 dev server 的 HMR host/clientPort 与外网一致
如果你用的是“外网域名 + 反代端口”,可以在 VitePress 的 Vite 配置里显式指定:
ts
// docs/.vitepress/config.mts
export default defineConfig({
vite: {
server: {
host: '0.0.0.0',
port: 11434,
hmr: {
host: 'ai.icetk.top',
clientPort: 11434
}
}
}
})实际上你项目里已经用了类似配置;如果 HMR 仍不稳定,优先检查 Nginx 是否正确升级 WS。
验证
- 打开浏览器 DevTools → Network → WS,确认存在 websocket 连接且状态为
101 Switching Protocols - 修改任意
docs/**的 markdown 文件,页面应能立刻热更新(不手动刷新) - Nginx access/error log 不应出现
upstream prematurely closed connection等异常
相关链接
- VitePress 文档:Runtime / HMR 与 Vite Server 配置(参考 Vite 配置项)
- Nginx WebSocket 反代:
proxy_set_header Upgrade/Connection