Laravelやってみる#3―BrowsersyncとHMR

Laravel 7.x

ぬにょす(挨拶)。

表題の通りですが、PHPフレームワークであるところのLaravelを使ってみようということで、やったこと・できたこと・できなかったこと等を自分の備忘録として残していきます。

#3の今回はビルド環境の整備です。

Browsersync

Laravelの公式ドキュメントにBrowsersyncリロードについての説明があります。ファイルの変更を検知して自動的にページを再読み込みしてくれるそうです。webpack.mix.jsを以下のように編集し、仮想マシン上で npm run watch を実行してからホストOSのブラウザで仮想マシンの3000ポートにアクセスすると無事に自動リロードが有効になりました。

webpack.mix.js
mix.browserSync({
  host: 'ubuntu1804.local',
  proxy: {
    target: 'http://ubuntu1804.local',
  },
  watchOptions: {
    usePolling: true,
    interval: 500,
  },
  open: false,
})

なお、初回の npm run watch は勝手にBrowserSyncなどの追加パッケージをインストールして終了…するかと思いきや、依存関係の警告?が出ました。

npm WARN browser-sync-webpack-plugin@2.0.1 requires a peer of webpack@^1 || ^2 || ^3 but none is installed. You must install peer dependencies yourself.

正しい対処法なのか分かりませんが、ncu を使って全パッケージを最新版にしてから再実行したところ、ファイル監視が始まりました。

[Browsersync] Proxying: http://ubuntu1804.local
[Browsersync] Access URLs:
 -----------------------------------------
       Local: http://localhost:3000
    External: http://ubuntu1804.local:3000
 -----------------------------------------
          UI: http://localhost:3001
 UI External: http://localhost:3001
 -----------------------------------------
[Browsersync] Watching files...

Bladeテンプレートを編集して保存すると期待通り再読み込みされました。

Hot Module Replacement (HMR)

npm run hot コマンドは、ブラウザの再読み込みなしにヌルヌルと変更が反映される、そんな素敵コマンドです。BrowserSyncがPHPファイルの変更でブラウザを再読み込みするのに対して、HMRはJavaScriptやCSSを動的に置き換えるようです(という認識です)。

BrowerSyncと共存できないかと四苦八苦・試行錯誤した結果、以下のように設定すると期待通りの動きになった感じがします。

webpack.mix.js
mix.options({
  hmrOptions: {
    host: 'ubuntu1804.local',
    port: 8080
  }
});
mix.webpackConfig({
  output: {
    publicPath: 'http://ubuntu1804.local:8080/'
  },
  devServer: {
    disableHostCheck: true,
    contentBase: path.join(__dirname, 'public'),
    publicPath: '/',
    host: '0.0.0.0',
    port: 8080,
    proxy: {
      '/': {
        target: 'http://localhost:3000',
      }
    },
    stats: { colors: true },
  },
  watchOptions: {
    poll: 2000,
    ignored: /node_modules/
  }
})

結果オーライな雰囲気が満載ですが、仮想マシン上で npm run hot コマンドを実行すると8080ポートでHMRが動いて、3000ポートでBrowserSyncが動きます。で、HMRはBrowserSyncのProxyにもなっている(という認識です…)。

正直、色々とオプションを設定したものの、何がどういう役割を果たしているのか正しく理解できていません(涙目)。ただ、期待通りの動きになったには違いないので、良しとします。

開発環境とリリース環境を分ける

BrowserSyncもHMRも開発時だけ有効になっていれば良く、逆にリリース環境ではキャッシュ対策としてバージョンナンバーを付与させたい。設定を環境で分けることにしました。

最終的な webpack.mix.js は以下のようになりました。

webpack.mix.js
const mix = require('laravel-mix');

/*
 |--------------------------------------------------------------------------
 | Mix Asset Management
 |--------------------------------------------------------------------------
 |
 | Mix provides a clean, fluent API for defining some Webpack build steps
 | for your Laravel application. By default, we are compiling the Sass
 | file for the application as well as bundling up all the JS files.
 |
 */

mix.js('resources/js/app.js', 'public/js')
    .sass('resources/sass/app.scss', 'public/css');

if (mix.inProduction()) {
    mix.version()
} else {
    mix.sourceMaps()
        .browserSync({
            host: 'ubuntu1804.local',
            proxy: {
                target: 'http://ubuntu1804.local',
            },
            watchOptions: {
                usePolling: true,
                interval: 500,
            },
            open: false,
        })
        .options({
            hmrOptions: {
                host: 'ubuntu1804.local',
                port: 8080
            }
        })
        .webpackConfig({
            output: {
                publicPath: 'http://ubuntu1804.local:8080/'
            },
            devServer: {
                disableHostCheck: true,
                contentBase: path.join(__dirname, 'public'),
                publicPath: '/',
                host: '0.0.0.0',
                port: 8080,
                proxy: {
                    '/': {
                        target: 'http://localhost:3000',
                    }
                },
                stats: { colors: true },
            },
            watchOptions: {
                poll: 2000,
                ignored: /node_modules/
            }
        })
}

次回は

ログイン系の処理をVueやaxiosでの処理に変えたい(希望)。

コメント

タイトルとURLをコピーしました