背景
- ローカル環境
環境
- Vite: 2.9.9
- Vue: 3.2.25
原因
- WebSocketの接続先に接続することができず、リロードされるようになっていた。
解決方法
- WebSocketの接続先のIPおよびポートが接続可能になるように、環境側の設定を変更した
詳細
構成イメージ
調査
- 以下の現象が起こっていた
-
https://vite-sample.com
にアクセスすると、数秒の間隔で画面が自動的にリロードされる - 開発者モードで確認すると、リロード直前に以下のような出力がされていた
開発者モード console
[vite] connecting...
WebSocket connection to 'wss://vite-sample.com:8084/' failed:
[vite] server connection lost. polling for restart...
- つまりWebSocketへの接続に失敗している
- これが無限リロードと関係しそうなので、コードの方の調査
- vite側で提供しているclient.tsの以下の個所が原因そうだと判明
- 以下にWebSocketの関連個所のみを抜粋
- client.tsを全体はこちらから参照
client.ts
// ...省略...
// use server configuration, then fallback to inference
const socketProtocol =
__HMR_PROTOCOL__ || (location.protocol === 'https:' ? 'wss' : 'ws')
// ここで接続先設定
const socketHost = `${__HMR_HOSTNAME__ || location.hostname}:${__HMR_PORT__}`
// viteの設定でlocalhostに置き換えた
const socket = new WebSocket(`${socketProtocol}://${socketHost}`, 'vite-hmr')
// ...省略...
// ping server
// ここでソケットへの接続が閉じたもしくは失敗した際に、リロードが発生する
socket.addEventListener('close', async ({ wasClean }) => {
if (wasClean) return
console.log(`[vite] server connection lost. polling for restart...`)
await waitForSuccessfulPing()
location.reload()
})
// ...省略...
- イメージとしてはこんな感じ
- 画面表示するようにポート:443は開けてる
- だけどWebSocketで使われるポート:8084は開けてない
対応
- 調査からWebSocketへの接続さえできれば無限リロードも解消されそうなことが分かった
- WebSocketが正常に接続できるようにするためには以下の方法が考えられる
- いまの接続先が正常に接続できるように、環境の設定変更で対応する
- 正常に接続できる接続先に置き換えるように、Viteの設定変更で対応する
環境の設定変更で対応案
- 今回のケースではこちらで解決した
- ALBでポート:8084も開けた
Viteの設定変更で対応案
- 今回は、あとから気づいたので、試していない(ので知見ある方いればコメントください・・・)
- vite.config.jsでWebSocket接続時に使用するポートを明示的に指定する
js.vite.config.js
// ...省略...
server: {
host: true,
port: 8084,
strictPort: true,
hmr: {
// ここに接続可能なポートを指定する
port: 443,
},
},
// ...省略...
まとめ
- Viteは内部でWebSocketの通信もしており、これも疎通していないといけない
- WebSocket向けの設定はhmrで行う