LoginSignup
4
3

More than 5 years have passed since last update.

Windowsだとlaravel-mixのhotが動かないんです><

Last updated at Posted at 2019-05-04

Windows上でyarn hotしたけど、うまくいかない場合の対処方法。

  • 環境(2019/05/05前後でインストールした):
    • laravel-mix: 4.0.7
    • webpack-dev-server: ^3.1.14
    • laravel: 5.8
    • node: 10.13
    • docker for windows使いつつ、jsはwindows上でビルド

TL;DR

下記設定を追記する。

webpack.mix.js
if (Mix.isUsing('hmr')) {
    mix.webpackConfig({
        output: {
            path: '/',
        },
        // webpackで生成してるもの以外をlaravelに取りに行く
        devServer: {
            proxy: {
                    '/':'http://localhost:8000/'
            },
        },
    });
}

説明

原因は生成先をwin絶対パスで指定したときに、dev-serverはwinパスで参照するが
webpackはposixパスに出力して、齟齬が出ているため。
なので、posixな絶対パスを指定して揃えて対応しています。

設定についての説明

output.pathは保存場所の基準となるパスです。
laravel-mixのデフォルトでは./publicの絶対パス(例:C:\work\laravel\public)やC:\ (HMR時)が設定されます。
これにより、mix.js('resources/js/app.js', 'js')と書いたら/js/app.jsに出力されることになります。
(なお、先頭のpublicは無視されるためmix.js('resources/js/app.js', 'public/js')と書いても同じ場所に出力されます)

ただ、このままだとyarn devした時に意図しないところに保存されるので、HMR時のみ有効化しています。

その判別に使ってるMix.isUsing('hmr')はコマンドライン↓の--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",

正体はこれ↓です。
laravel-mix/src/config.js
https://github.com/JeffreyWay/laravel-mix/blob/ac70a860efd1f548582de97fca017d49113aa0ed/src/config.js#L17
なお、ここで使っているMixは明示的にインポートしてるmixとは違って、
インポート元がグローバルに定義してしまっているので使えてしまっているものです。

ちなみに、mix.webpackConfig() はlaravel-mixで生成したwebpack.config.jsの内容を上書きしてくれるものです。

Readouble カスタム設定のマージ
https://readouble.com/laravel/5.8/ja/mix.html#custom-webpack-configuration

細かい話と改変する際の注意事項

proxyについて

本件とは全く関係ないですが、「webpack-dev-serverはphpを解釈してくれないから変わりにindex.htmlを置くのだ―」という記事をどこかで見かけたので、念の為記載しました。

devServer.writeToDisk は設定しても動かない

devServer.writeToDisk
https://webpack.js.org/configuration/dev-server/#devserverwritetodisk-

実ファイルも生成してくれるようにするオプションですが、今回、出力場所を変えている都合上、期待した場所とは違う場所にファイルが作られることになります。
なお、laravel-mix標準でも出力場所変更を行っているので、やはりうまく行きません。

laravel-mix/src/builder/WebpackConfig.js
https://github.com/JeffreyWay/laravel-mix/blob/ac70a860efd1f548582de97fca017d49113aa0ed/src/builder/WebpackConfig.js#L53-L73

devServer.port は変えるな

devServer.port
https://webpack.js.org/configuration/dev-server/#devserverport

初回読み込み時は問題ないんですが、HMRで差分を取りに行ったときに、localhost:8080に読みに行こうして、動かなくなります。多分バグな気がします。

蛇足ですが、hmrOptionsを設定していると、このdevServer.portを指定していることと同じ事になるので注意してください。

蛇足: bladeファイルを編集したのに更新されない!

HMRはjsの話なのでbladeの変更には追従しません。
多分このあたりの設定で完全リロードがされると思います。
https://webpack.js.org/configuration/dev-server/#devserverwatchcontentbase

うまく動かない環境があるかも

変更差分を取りに行くパスがちょっとおかしいです。具体的には↓のように//が入ります。
http://localhost:8080//js/app.8f71ce5aef303e29563a.hot-update.js

現状誰かが吸収してくれてるみたいなので、問題なく動いていますが
ブラウザ、もしくはwebpack-dev-serverのバージョンによってはうまく動かないかもしれません。

もうちょっと詳しい状況説明

laravel-mixがoutput.pathを決めている場所がここ↓なのですが、
path.resolveで(そのプラットフォームの)絶対パスを指定してしまっています。

laravel-mix/src/builder/webpackConfig.js
https://github.com/JeffreyWay/laravel-mix/blob/ac70a860efd1f548582de97fca017d49113aa0ed/src/builder/WebpackConfig.js#L61-L62

そして、Windowsな絶対パスを指定されるとdev-server側がうまく動作しないようです。
具体的には、webpackがlinuxパスの/js/app.jsに出力し、
dev-serverがwinパス?のC:\js/app.jsに取り行こうとして失敗している感じです。

本件とあまり関係ない気がしますが、このあたり胡散臭いです。
path.posix.joinを使ってるので、C:\js/app.jsみたいなゴッチャになったものを出力していますし…
ただ、ここをwin32に変えてもダメそう。

webpack-dev-middleware/lib/util.js
https://github.com/webpack/webpack-dev-middleware/blob/6d191d02f391fbac885e29f2520dcfc899e4c662/lib/util.js#L106

多分、dev-server側のパス処理をwebpack側に寄せれば良いと思います。
が、Windowsのパスで渡してるのに、linuxなパスに変換して書き込んでるwebpackはどうなの?という気もしますし…

4
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
3