Nuxt3 は、ポートフォワーディングをせずに内部の local だけで開発が完結する場合は、何も考えずに WebSocket を使ってホットリロードしてくれます。
下記の左図は、通常のシンプルな開発環境(localhost:3000)における開発の図で、右図が ngrok を介した場合の Nuxt3 の開発です。
ngrok を介した開発では、local の任意のポートをポートフォワーディングしているため、https 付きのアドレスが吐き出されます。
しかし、Nuxt3 と ngrok を組み合わせて開発を行う際、ホットリロード(Hot Module Replacement, HMR)がうまく動作しないという問題に遭遇することがあります。
この記事では、そのような問題を解決する方法を紹介します。
設定失敗の例
Nuxt3 と Vite を使用している場合、nuxt.config.js で Vite の設定を行います。
当初、ngrok にポートフォワーディングしている状態で、ホットリロードを行う際に以下のように誤った設定をしていました。
// nuxt.config.js vite: { server: { https: true, hmr: { protocol: 'wss', host: 'localhost', clientPort: 443, path: 'hmr/', }, }, },
この設定ではHMRが正常に動作しない問題が発生します。
path
に設定されている hmr/
が、指定されている clientPort
では解決できずに、延々とリトライを繰り返してしまう結果になります。
また、path
を消去したとしてもエラーが発生します。
HTTPS 通信の場合のプロトコルは、確かに protocol: 'wss'
で間違いないのですが、port: 443
で通信しようとしているため、こちらはすでに利用されているポートとして弾かれる結果になります。
解決方法
問題の解決には、nuxt.config.js の Vite の設定をシンプルにすることが有効でした。
// nuxt.config.js vite: { server: { hmr: { host: 'localhost', }, }, },
詳しい設定を書くと下記のようになります。 ※この書き方をわざわざしなくても上記の設定だけで十分ですが、今回は説明のために敢えて詳細の設定(デフォルト値)を記載しています。
// nuxt.config.js vite: { server: { host: '0.0.0.0', port: 3000, hmr: { protocol: 'ws', host: 'localhost', port: 24678, }, }, },
protocol: 'wss'
とclientPort: 443
を削除することで、不必要なセキュリティ設定が排除されました。ホスト設定
host: 'localhost'
を残していますが、これは ngrok がローカルホストにトンネリングするためです。hmr のポート設定は、デフォルトの24678を設定することです。ここで誤って3000を指定しないようにしてください。
ポイント
ngrok は自動的に WebSocket もトンネリングしてくれるので、HTTPS 通信など考えず、特別な設定は不要です。
以上のように、設定をシンプルにすることで HMR の問題が解決しました。 Nuxt3 と ngrok を使った開発を行う際には、このような設定が有効です。
参考にしたサイト
Vite公式ドキュメント(server.hmr設定)
https://ja.vitejs.dev/config/server-options.html#server-hmr
ngrok公式ドキュメント(WebSocketのトンネリングについて)
https://ngrok.com/docs/using-ngrok-with/websockets/
Vite GitHubリポジトリ(Sever モデルの選択について)
GitHub - sapphi-red/vite-setup-catalogue: This repository contains several example of Vite setups.