moxt

Just another Blog site

WebpackerとWebpacker::DevServerProxy

   

Rails6がリリースされた。
Rails6からjavascriptの管理はWebpackerで行うみたい。

Webpackerを導入すると、webpack-dev-serverコマンドが使えるようになる。
jsファイルの変更を監視してビルドし、ファイルの配信、ブラウザのリロードまでしてくれる。

ファイル配信について疑問があった。
webpack-dev-serverを起動するとlocalhost:3035でリクエストを待ち受けてる。
ただ、よくあるRailsアプリを起動するとlocalhost:3000でリクエストを待ち受けてる。
で、packs以下のファイルを http://localhost:3000/packs/js/application-106dae08824fadbcd45a.js とかで取得することができる。
『あれ http://localhost:3035/packs/js/application-106dae08824fadbcd45a.js が正しいのではないか?』と思ったわけ。

どうやらミドルウェアで処理をしてるみたいだ。

https://github.com/rails/webpacker/blob/master/lib/webpacker/dev_server_proxy.rb

DevServerProxyで受け取ったリクエストを弄ってる。
DevServerProxyはRack::Proxy( https://github.com/ncr/rack-proxy )を拡張したモノだ。

Rack::Proxyのperform_requestメソッド( https://github.com/ncr/rack-proxy/blob/master/lib/rack/proxy.rb#L72 )でNet::HTTPを使って、改変されたリクエスト情報を投げ、結果を取得してる。

DevServerProxyのコードは下記の通り。

if env["PATH_INFO"].start_with?("/#{public_output_uri_path}") && dev_server.running?でURLのパスと、webpack-dev-serverの起動をチェックしてる。

public_output_uri_pathはconfigのwebpacker.ymlで指定されてるディレクトリだ。
特に何も設定してなければpacksになってる。

つまり、packs以下のファイルにアクセスしようとするとリクエストがwebpack-dev-serverにフォワーディングされるわけだ。

if文の中ではenvの書き換えを行ってる。
env[“HTTP_HOST”]はwebpack-dev-serverのホストに書き換えられてる。
最後にsuper(env)を呼び出してるので、Rack::Proxyのperform_requestの中で改めてリクエストを投げて、その結果を返してくれる。

余談だが、webpack-dev-serverを起動してもCannot GET XXX[ファイル名]と表示される場合は、webpack-dev-serverが複数起動してる可能性がある。
私は複数のプロジェクトをdockerを使って開発していたため、webpack-dev-serverを同ポートで複数起動していた。
当たり前なんだけど、これが原因で別プロジェクトのpacks以下のファイルが取得できず困っていた。

 - Rails

336px




336px




  • このエントリーをはてなブックマークに追加
  • follow us in feedly

  関連記事