LaravelでのBrowsersyncを理解して外部開発WebサーバーにあるSSLのLaravelプロジェクトでも自動リロードを実現したい！

各自におかれましてはLaravelで本日もごにょごにょ楽しんでおられることと思い、嬉しく思います。
最近はLaravelを納品に使うことも増えましたので気持ち良い開発環境を構築したい今日このごろです。
さて、今回はファイル変更を検知してブラウザの自動リロードをしたいです。
私の環境ではちょっとしたコツが要りましたのでまとめ。
公式ドキュメントを詳らかに読んだわけではないので、とりあえず、こうやったらうまく動くよ、という記事となります。

公式ドキュメント
https://browsersync.io/docs/options

## 環境

下記環境で確認しています

* Laravelプロジェクトは自マシンではなく、外部の開発サーバーに存在
* 開発サーバーでは本番同等にphp-fpmなどを使ってWebサーバー経由でプロジェクトを配信
* 開発サーバーでは本番同等に常時SSL化している

開発サーバーというよりステージングサーバーに近い環境です。
私は自マシンを信用していないのでバックアップスクリプトも走っている開発サーバーで作業することが多いです(客のチェックもリアルタイムにできるのでプロジェクトも進めやすい)。
自マシンでやる場合はもうすでに他の方の記事があるのでGoogle検索してください。ただし、この記事を読めばわりと柔軟に対応できると思います。まずLaravelをBrowsersyncなしで動作させ、それにappendでBrowsersyncをくっつけるイメージでいけばだいたいなんとかなります。

## Browsersyncとは

Laravelを標準的にインストールしたら一緒に入ってくるファイル変更検知で自動ブラウザリロードの仕組みです。

## LaravelプロジェクトでBrowsersyncを使ったリクエストをさばく仕組み

Browersyncは下記のような動作でリクエストをさばきます。

### リクエストをインターセプト

BrowserSyncはListenしているhost、portでリクエストをインターセプトします。

### proxy配下へリクエストをバケツリレー、なんか付加してブラウザへレスポンスを返却

* proxy配下へリクエスト内容をバケツリレーします(ここがProxyのこと)
* 配下から返却をBrowserSyncが取得
* BrowserSyncはリロードの仕組みを返却に付与
* レスポンスをブラウザへ返却

## 自動リロードの仕組み

わかれば簡単なのですが下記の動きをします。(前項にてサーバー側からブラウザへ命令を送信できる仕組みができています。)

### チェック設定のファイルの変更を検知

設定ファイルのfilesに設定した内容でファイルシステムの変更をチェックします。

### 変更があればブラウザリロード命令を発行

* レスポンスに付与した仕組みを使ってブラウザへリロード命令を送ります。
* ブラウザは画面のリロードを実行

やったね。

## 実際の設定/コマンド

実際の設定/コマンドは下記となります。

### webpack.mix.jsの内容
最小構成で下記となります。

```javascript
mix.js('resources/js/app.js', 'public/js') // ただのmixだな
   .sass('resources/sass/app.scss', 'public/css') // ただのmixだな
   .browserSync({ // ここから
     proxy: {
        target: "http[s]://あなたのLaravelプロジェクトトップへアクセスできるURL" // 最後に/は不要
     },
     https: true, // httpsのサイトをproxyするならtrueをセット
     files: [ // チェックするファイルは下記で十分ではないかな。
       './resources/**/*',
       './app/**/*',
       './config/**/*',
       './routes/**/*',
       './public/**/*'
     ],
     open: false, //BrowserSync起動時にブラウザを開かない
     reloadOnRestart: true //BrowserSync起動時にブラウザにリロード命令おくる
});
```

* `proxy.target`のURLがhttpsのサイトの場合は`https`は`true`にしてください
* filesに'./**/*'とかしているとファイル多すぎてBrowsersyncが落ちます

### 設定(Firewall)
デフォルトの3000番でBrowserSyncのListenが入りますので3000番をFireWallで通してください。

```shell
$ sudo ufw allow 3000
$ sudo ufw reload
```
### `npm run watch`でBrowsersyncの起動

```
$ cd [your project path]
$ npm run watch
```

`npm run watch`にてデフォルトポート3000番でBrowsersyncが動作開始します。
下記のような表示がコンソールにでますので

```txt
[Browsersync] Proxying: https://xxxxxxxxxxxxx
[Browsersync] Access URLs:
 ---------------------------------------
       Local: https://localhost:3000
    External: https://192.168.xxx.xxx:3000
```

`External:`のURLにアクセスすればOKです。


## 他設定例

### `php artisan serve`で起動したLaravelへアクセスする場合

`webpack.mix.js`は下記になります。

```javascript
mix.js('resources/js/app.js', 'public/js') // ただのmixだな
   .sass('resources/sass/app.scss', 'public/css') // ただのmixだな
   .browserSync({ // ここから
    proxy: {
        target: "http://127.0.0.1:8000" // 最後に/は不要
    },
    files: [ // チェックするファイルは下記で十分ではないかな。
       './resources/**/*',
       './app/**/*',
       './config/**/*',
       './routes/**/*',
       './public/**/*'
    ],
    open: false, //BrowserSync起動時にブラウザを開かない
    reloadOnRestart: true //BrowserSync起動時にブラウザにリロード命令おくる
});
```

ターミナル１つ目で`php artisan serve`

```shell
$ (sudo) php artisan serve --host 0.0.0.0
```

場合によってはsudoいるかも。既存で動いているLaravelプロジェクトをいじっているプロセスがあればパーミッションデナイドでエラー画面になりました。


ターミナル２つ目で`npm run watch`

```shell
$ npm run watch
```
## まとめ
Browsersyncの待受ポートとか変更したい場合は公式ドキュメントにあるので参考にしてください。
調べてみると既存記事よりもずっとシンプルな設定に落ち着きました。
enjoy.

## 参考

* https://stackoverflow.com/a/46971719/5598088
* https://github.com/paulmillr/chokidar