windowsのdockerの環境をhyper-vからwsl2に乗り換えた時にnpm run watchが聞かなくなったので、npm run watch-pollに切り替えました。
が、npm run watch-poll をするとcpuの負荷が重すぎてファンがうるさかったので、なんとかcpu負荷を軽減できないかと対策したときのメモ。
結論
laravelのプロジェクト直下のpackage.jsonに対して
{
"scripts": {
"watch-poll": "npm run watch -- --watch-poll=5000",
},
}
と時間(watch-poll=5000で5000ms=5sの意味)を指定しましょう。(参考[1])
#解説
watchとwatch-pollの違い
そもそもwatchはwebpackの仕組みです。
ファイルを監視し、ファイルの変更があった時に差分だけをトランスパイル先にアップロードしてくれます。
watchのおかげで、何回も全体のトランスパイルを繰り返すことなく、最小限の時間で更新を確認することができます。
このwatchは仕組みとしては、ファイル変更のイベントを検知して、それに処理をするようです。
なので、ファイルシステムやパスの等に問題が発生して適切にファイル変更のイベントを受信できなければwatchは機能しません。[注釈1]
watchが動作しない環境のために、webpackにはpollというオプションがあります。
webpackのwatchが変更の通知を待つのに対して、pollはwebpackから更新処理を定期的に確認しにいきます。
webpackをラップしているlaravel-mixでは、pollオプション付きのwatchが--watch-pollで使用することができます。
watch-pollの処理間隔の仕様
pollingの間隔はデフォルトでは1秒になっています。
webpackにおいて、処理の間隔は変更が可能です。
Laravel-mixでも--watch-poll=(時間) とすればpollingの間隔を変更できます。
注釈
- 自分の場合はwsl2のdockerコンテナで稼働するlaravelを使っています。
この場合は、vscode等によるwindows上でのファイルの変更がdockerの使っているwsl2上のlinux(ubuntu)に通知されなかったことが原因です(参考[2])。
vscodeの場合はremote-wslでホスト元となっているディストリビューションを使えば、ファイルの変更がwsl2に通知されるため、npm run watchを使用することができるという話もあります。ただ自分の環境では試してみたらダメだったので、気が向いたり必要になったら調査するかもしれません(wslベースでvscodeするなら移行するデータも多いし、とりあえずはwatch-pollで十分なため)。
#参考
[1]https://github.com/JeffreyWay/laravel-mix/issues/1418
[2]https://github.com/microsoft/WSL/issues/4739