Docker環境のLaravel+VueでHMR(Hot Module Replacement)を動かす

2020/12/29

Docker DesktopをWSL2にしたことでHMR(Hot Module Replacement)が動くようになるかもしれないと思い試してみました。結果うまくいきましたが、コンテナをWeb・PHP・Nodeと分けている場合の設定に手間取ったので、誰かの役に立てばと思い記録に残しておきます。

スポンサーリンク

環境

  • Windows10 Pro (バージョン 1909)
  • WSL2(Distribution: Ubuntu20.04LTS)
  • Docker Desktop 3.0.0
  • コンテナの種類
    • Apache2.4
    • PHP7.4(FPM)
    • Node15.5

コンテナの設定

下記のような設定になってます。※ 重要なところだけ抜粋

docker-compose.yml

version: '3'

services:
  apache24:
    ports:
      - "8080:80"
  php74:
    ports:
      - '9000'
  node:
    image: node:latest
    ports:
      - "3000:3000"
      - "3001:3001"

※ nodeの3000と3001ポートはbrowserSyncで使用するための設定です。

HMRの設定

デフォルトは下記の設定で動作します。

参考: https://webpack.js.org/configuration/dev-server/

  • host: localhost
  • port: 8080

8080がHMRの待ち受けポートのデフォルトですが、WEBサーバ側のポートと被ってしまってます。WEBサーバ側ポートに特に意味はないので変えてしまってもよかったのですが、HMRの方のポートを変えてしまうほうが早いと思いました。が、これが小2時間ほどはまってしまいました。。。

もともと3000ポートはbrowserSyncで使用していたので、このポートをHMRで使用するようにします。

webpack.mix.js

// Browser Syncの設定をコメントアウト
// mix.browserSync({
//   files: [
//     "./resources/views/**/*.blade.php",
//     `./../html/assets/admin/js/*.*`,
//     `./../html/assets/admin/css/*.*`
//   ],
//   proxy: {
//     target: 'http://apache24:8080'
//   },
//   open: false,
//   reloadOnRestart: true,
// });

// HMR用設定を追加
mix.webpackConfig({
  devServer: {
    host: '0.0.0.0',
    port: 3000,
    proxy: {
      '*': 'http://apache24:8080'
    }
  }
});

起動!

npm run hot
> hot
> cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js

ℹ 「wds」: Project is running at http://0.0.0.0:3000/
ℹ 「wds」: webpack output is served from http://localhost:8080/
ℹ 「wds」: Content not from webpack is served from /workspace/hakujyuji_renew/html
ℹ 「wds」: 404s will fallback to /index.html
Browserslist: caniuse-lite is outdated. Please run next command `npm update`

むむむ、なにやらhttp://localhost:8080/とデフォルトポートで動作している箇所があります。

WebpackのDevserver側設定をドキュメント見ながら怪しい所を変えても全然だめ。publicとかの設定を追加してみましたが、compileのログ上は変わっても実際動作させるとlocalhost:8080を見に行ってしまい、jsなどが404に。。 (ここで2時間ほど試行錯誤してしまった。。)

ふとLaravel Mixが何かしてるのかなーと思いドキュメント・ソースを見てみるとありました、HMR用の設定が。

ということで最終系はこちら。

mix.options({
  hmrOptions: {
    host: 'localhost',
    port: 3000
  }
});
mix.webpackConfig({
  devServer: {
    host: '0.0.0.0',
    port: 3000,
    proxy: {
      '*': 'http://apache24:8080'
    }
  }
});

これで無事に動作するようになりました。
今回は元々browserSyncで使用していたポートを使ってしまったのですが、適当にずらしてしまえばbrowserSyncも使えます。ただ、個別に起動なので同時には使えません。共存する方法があるかを今度試してみようかと思います。