仮想環境で開発中 JavaScript が途中で途切れて壊れる場合の対処法

Vagrant (VirtualBox) + Apache + Webpack でコンパイルされた JavaScript や CSS が途中で途切れて壊れる場合の対処法を紹介します。

gulp.js の watch モードで JS が壊れる

フロントの開発時、gulp.jsのwatchモードを用いてwebpackコンパイルを自動で行うよう設定されているプロジェクトで開発していていました。
しかし、なぜか半分の割合で、生成されたJSが途中で切れてしまいます。当然ブラウザ上ではエラーで停止します。
ファイルを直接見るとまったく問題がなく、Apacheの再起動を行うとすぐに復活するため、Webサーバーのキャッシュの問題を疑いました。

原因

EnableSendfileというApacheの機能が影響していました。
core - Apache HTTP サーバ バージョン 2.4
https://httpd.apache.org/docs/2.4/mod/core.html#enablesendfile
公式ドキュメントには下記の記載があります。
デフォルトでは、 例えば静的なファイルの配送のように、リクエストの処理にファイルの 途中のデータのアクセスを必要としないときには、Apache は OS が サポートしていればファイルを読み込むことなく sendfile を使って ファイルの内容を送ります。
そして、その下に「しかし、プラットフォームやファイルシステムの中には 運用上の問題を避けるためにこの機能を使用不可にした方が良い場合があります:」という記載があります。
ネットワークマウントされた DocumentRoot (例えば NFS や SMB) では、カーネルは自身のキャッシュを使ってネットワークからのファイルを 送ることができないことがあります。
ファイルのキャッシュが中途半端なタイミングで行われてしまい、途中で途切れた状態が出力されてしまうというのが原因なようです。
下記の記事のようにNFSを使用するように設定している場合に発生します。VirtualBox初期設定のファイル共有では発生しません。
Vagrant(VirtualBox)でディスクアクセスが遅い問題の対処法
https://bicstone.me/vagrant-laravel-slow/

EnableSendfileを無効にする

EnableSendfile 機能を無効にします。若干の速度低下があるようですが、(VirtualBoxを用いている時点で遅いので)よっぽど大量のリクエストを行っていない場合は問題ありません。
httpd.confのEnableSendfileをOffにします。
EnableSendfile off
または、.htaccessに設定します。
EnableSendfile off

@bicstone

大石貴則 (Ōishi Takanori) と申します。 Webエンジニア / セキュリティスペシャリスト / 機械エンジニア です。 プロダクトに幅広く携わり、相互成長し続けられるエンジニアを目指しています。

GitHubLinkedIn