墨と鉛筆

書いてみる。描いてみる。

WindowsホストでVirtualBoxでLaravel-Mix 、やっとできた

Laravel-Mixが使いたかった

開発環境はWindowsマシンをホストとして、VirtualBoxのサーバにCentOS+PHP+Laravel。
作業はWindows上で行うので、VirtualBoxの共有フォルダ(vboxsf)でLaravelのプロジェクトフォルダを共有していた。
そうすればソースの修正は即座に反映されるし、artisanコマンドはCentOSで叩けばよい。

ところが、問題が起こった。
Laravel-Mixが動かない。

具体的には、手順通りに

npm install

とやっても、うまく動かない。 エラーがでる。

npm ERR! Linux 3.10.0-514.26.2.el7.x86_64
npm ERR! argv "/usr/bin/node" "/usr/bin/npm" "install"
npm ERR! node v6.11.3
npm ERR! npm v3.10.10
npm ERR! path ../acorn/bin/acorn
npm ERR! code EROFS
npm ERR! errno -30
npm ERR! syscall symlink

npm ERR! rofs EROFS: read-only file system, symlink '../acorn/bin/acorn' ->
'/media/sf_php/proj/node_modules/.bin/acorn'

原因は?

どうも、npmで依存解消のためにダウンロードするnode_modules配下のJavaScriptモジュール群ではダウンロード量を節約するため、シンボリックリンクを使うらしい。 でも、VirtualBoxの共有フォルダはシンボリックリンクに対応していないらしい。 なるほど。

対策としては、npm install の実行時に「--no-bin-links」を指定すればシンボリックリンク使わないよ!とのこと。 試してみたところ、npm install はひとまず終わったが、今度はLaravel-Mixの実行時にエラーとなる。

今度のエラーは 「ディレクトリパス名が長すぎて、Windowsのパス長の制限を超える」 というのが原因のようだ。 シンボリックリンク使わなくなった結果、階層が深くなり、パス長がOSの制限を超えたらしい。まじか。

結論としては「Windowsのシステム上で、CentOSが扱うnode_modulesは置いておけない」ということのようだ。
これで、詰んだ。

ネット上で見た他の人は * node_modulesだけをVirtualBox共有フォルダの外に置く * Laravel-MixまるごとをVirtualBox共有フォルダの外で実行し、コンパイル済ファイルだけをLaravelプロジェクトに都度コピーする * VirtualBox共有フォルダでシンボリックリンクを扱えるようにしてしまう 等々、いろんなやり方でやっているようだが、とにかく手間がかかる。 3つ目の方法などは自分も真似してみたが、手順が複雑でなかなか思うように進まなかった。

しばらくの間、「ウチの環境ではLaravel-Mixは使えないのだ。さらば、モダンJS。さらばVue.js。」とあきらめていた。

mount bind というワザ

福音となったのは、Qiitaの下記の記事。

Windowsホスト上のVagrantの共有フォルダでnpmに失敗する問題の解決 - Qiita

記事の内容も自分の状況にドンピシャだったが、そのコメント欄に神からの救いの手が・・・

engineer

https://medium.com/@dtinth/isolating-node-modules-in-vagrant-9e646067b36
これでもっと簡単に解決できるかもしれないです。

リンク先を見ると、「mount --bind」でできるよ、とのこと。
まじ?? bindって何?初めて知りました。

やってみた、できた

とにかく、やってみる。
下記の要領で、CentOSで実行する。これってシンボリックリンクと何が違うんだろうか、と半信半疑ながら。

mount --bind /var/node/proj-node_modules /media/sf_php/proj/node_modules

なお、マウントポイントとなるディレクトリ(上記例の/var/node/proj-node_modules)は先にmkdirしておくのがマナーのようだ。
すんなりとコマンドは完了した。そして、確かにマウントできている。片方でファイルを作ると、もう片方でも読み書きができる。ふむ、なるほど。
シンボリックリンクと違うのは、Windows側でエクスプローラでproj/node_modulesを見ると、内容がからっぽに表示されるところ。

この状態で、CentOSでLaravel-Mixを実行する。

cd /media/sf_php/proj
npm install
npm run dev

できた!!できたよ!! ちゃんとapp.jsもapp.cssもできてる!Vue.jsもちゃんと動く!!すごい!

マウントの永続化

上記のmountコマンドを打つだけではCentOSをリブートするたびにコマンドを打つことになるので、起動時に自動でマウントするよう、/etc/fstab に下記の1行を追加する。

/var/node/proj-node_modules /media/sf_php/proj/node_modules none rw,bind,_netdev 0 0

めでたし、めでたし

これまで試行錯誤した中で一番設定が簡単で日々の開発効率が高い方法だと思う。

約半年くらいあーだこーだやっていてダメだったのが解決したので嬉しい反面、やはりこの方法でもどこかに落とし穴があって、またハマるのはないかと心配ではある。
今日つながったばかりなので、今後また障害などがあれば記事にしようと思います。