webpackerを使ったRailsプロジェクトでは多くの場合webpack-dev-serverを同時に動かしておくことが多いと思われます。

ところがそのwebpack-dev-server、配信側もアプリ側もポート番号が3035に固定されているように見えます。

これでは複数のRailsアプリケーションを動かしたいときに、ポートが衝突してしまって1つしかwebpack-dev-serverを起動できない事態になってしまいます。

環境変数によってポートを変更する方法

まずは結論から。

rails serverwebpack-dev-serverのコマンドの両方に↓の環境変数を追加すればOKです(たとえばポートを3036に変えるとしましょう)

  • WEBPACKER_DEV_SERVER_PORT=3036
  • WEBPACKER_DEV_SERVER_PUBLIC=localhost:3036

(ただ動くようにするためには、webpack-dev-server側の…_PUBLICの環境変数は不要です。ですが、webpack-dev-serverのログには…_PUBLICのURLが表示されており、それはそれで気持ち悪いので両方にセットするのが無難です)

環境変数がどこで有効になるのか

webpack-dev-server

webpack-dev-serverでは設定ファイルのyamlを読み込んだあと、ポートなどの値を取りに行きます。 そのとき、環境変数側に値があれば環境変数を優先するというロジックになっていました。

https://github.com/rails/webpacker/blob/master/lib/webpacker/dev_server.rb#L62-L64

JS側

Rails起動時にconfig/webpack/development.jsが読まれます。 このとき、内部ではここのコードが呼び出されており、さらにその先で環境変数がある場合は優先するような記述があります。

https://github.com/rails/webpacker/blob/master/package/dev_server.js#L13-L14

おわり

環境変数が長ったらしいこともあり、これらの環境変数をコマンドに毎回付与するのはあまり実用的じゃありません。 ですが、当面は1回目だけ頑張って入力して、それ以降はコマンド履歴から探すというのが楽そうです。 環境変数で指定するだけであればプロジェクトメンバー全員で統一する必要もありませんしね。

以下ただの感想です。

これらの環境変数についてはあまりドキュメントに書かれておらず、結局コードを読んでいくはめになりました。 環境変数名がわかってからリポジトリ内を調べてみると、一部ドキュメントがありましたのでリンクしておきます。

rails/webpacker
Use Webpack to manage app-like JavaScript modules in Rails - rails/webpacker

Cloud9だとこう使うよ、というドキュメントにポートなどを個別にしていするためのやり方が載っていました。 そっちかよという気持ちです。