WindowsのDockerによるVite+React+TypeScript環境でHMRが効かないときの解決方法

2024/01/31に公開

Viteを利用してnpm create vite@latest <project-name>からReactとTypeScriptの開発環境を作ってみました。
ソース読み込みをDockerコンテナ側に担わせてブラウザに画面を表示させるまではできたのですが、開発しているとWindows PCではソース変更をブラウザへ自動で反映してくれる機能が働きませんでした(この仕組みをHot Module Replacementというそうですが、この件で調べていて初めて知りました)。

調査していると、どうやら初期設定から少し追記が必要だったようです。忘れても困らないように解決策を記事に残しておきます。

結論: usePolling: trueを追記する

vite.config.tsに{usePolling: true}を追記します。

vite.config.ts
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react-swc"

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
+  server: {
+    watch: {
+      usePolling: true, // 追記する
+    },
+  },
})

https://github.com/vitejs/vite/issues/1153
で同じような事象があり、参考にさせていただきました。

CPU利用率を下げる

usePolling: trueを設定するとCPU利用率が高くなってしまうようです。
参考までに、私のPCでタスクマネージャーを開いてみると常に30%付近になっていました。

詳しいオプション設定のことが書かれたページによると、ファイルの監視周期がデフォルトでは100ms(バイナリファイルは300ms)周期になっているようです。

  • Polling-specific settings (effective when usePolling: true)
    • interval (default: 100). Interval of file system polling, in milliseconds. You may also set the CHOKIDAR_INTERVAL env variable to override this option.
    • binaryInterval (default: 300). Interval of file system polling for binary files.

に従って周期を下げてみると、CPU使用率を抑えられました。

ここでは普通のファイルを1000ms, バイナリファイルを1500msくらいにしてみた結果を記載します。数値は適当に決めているので手元のPCの負荷を見て調整した方が良いかもしれません。

vite.config.ts
import { defineConfig } from "vite"
import react from "@vitejs/plugin-react-swc"

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [react()],
  server: {
    watch: {
      usePolling: true,
+       // CPU負荷軽減のため監視周期を下げる
+       interval: 1000, // default: 100
+       binaryInterval: 1500, // default: 300
    },
  },
})

この設定でCPU使用率が1ケタ%に収まりました!

参考にした記事

Discussion