今回はVagrantで構築した仮想マシン上のLaravel動作環境にnpmをインストールし、実行できるようにして行きます。
「フロント部分をVueで作ろう」と意気揚々とnpmのインストールを始めたら、エラーで詰まりまくったので解決方法をシェア。
今回の環境
ホストOS:macOS Catalina 10.15.2
VirtualBox:6.0.18r136238
Vagrant:2.2.7
CentOS:7.4.1708
Laravel:5.5.49
やりたいことの確認とエラーの原因
まずは今回やりたいことの確認です。
①Vagrantを使用して構築した仮想マシン(VirtualBox)上でLaravelの動作環境を作っている。
②Laravelのアプリ全体がVirtualBoxの共有フォルダとして共有されている。
③Vagrant上のLaravelアプリ内でnpm install、npm run watchなどを行えるようにしたい。
③が鬼門で、普通にVagrant上のlaravelアプリ内でnpmインストールしてしまうと、
npm ERR! Maximum call stack size exceeded
のようなエラーが出ます。
npmで依存解消のためにダウンロードするnode_modulesのモジュール群では、シンボリックリンクを使うらしいです。
しかしVirtualBoxの共有フォルダはシンボリックリンクに対応していないのでこのエラーが出ます。
このエラー自体は、以下のコマンドで解消でき、インストール自体はうまくいくようですが...
npm install with --no-bin-links
このコマンドでインストールしても、今度はnpm run devやnpm run watchなどのコマンドで実行時にエラーが出て動かない。
これらのエラーをすべて解決できる方法を解説していきます。
Vagrantにnodeとnpmをインストールする
まずはインストールに必要なnodeとnpmからインストールしていきます。
Vagrantからnvm(node version manager)をインストール
vagant ssh
でログインして、Vargant内部にgitがあるかどうかを確認します。
[vagrant@local-docker ~]$ git --version
git version 1.8.3.1
入っていない場合は以下のコマンドでインストールします。
[vagrant@local-docker ~]$ sudo yum -y install git
gitがインストールできたら、nvmをclone していきます。
[vagrant@local-docker ~]$ git clone https://github.com/creationix/nvm.git ~/.nvm
Cloning into '/home/vagrant/.nvm'...
remote: Enumerating objects: 2, done.
remote: Counting objects: 100% (2/2), done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 7495 (delta 0), reused 1 (delta 0), pack-reused 7493
Receiving objects: 100% (7495/7495), 2.40 MiB | 1.74 MiB/s, done.
Resolving deltas: 100% (4737/4737), done.
nvmをbash_profileに反映
インストールしたままだと使用することができないので、bash_profileと呼ばれる、起動時に必ず実行するbashの設定ファイルに反映させる必要があります。
まずは、ls -la
というコマンドですべてのファイルを表示します。
[vagrant@local-docker ~]$ ls -la
合計 80
drwx------. 10 vagrant vagrant 222 5月 4 05:28 .
drwxr-xr-x. 3 root root 21 4月 11 2018 ..
-rw-------. 1 vagrant vagrant 5233 5月 5 00:34 .bash_history
-rw-r--r--. 1 vagrant vagrant 18 8月 2 2016 .bash_logout
-rw-r--r--. 1 vagrant vagrant 264 5月 4 02:18 .bash_profile
-rw-r--r--. 1 vagrant vagrant 231 8月 2 2016 .bashrc
#省略
vi
コマンドでbash_profileを編集していきます。
[vagrant@local-docker ~]$ vi .bash_profile
上記コマンドを打つと以下のような画面になるので、まずはi
を押してinsertモードにします。
#ここから追加から#ここまでと書いてある記述を追記してください。
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
PATH=$PATH:$HOME/.local/bin:$HOME/bin
export PATH
#ここから追加
#nvmの実行
if [[ -s ~/.nvm/nvm.sh ]];
then source ~/.nvm/nvm.sh
fi
#ここまで
編集したら、escキー
を押して:wq
というコマンドを打って保存します。
保存し終えたら、一度exit
で出て、再度vagrant ssh
でログインししてください。
再ログインしたら、以下のコマンドで確認します。
Node Version Managerの記述がでていたら成功です。
[vagrant@local-docker ~]$ nvm help
Node Version Manager (v0.35.3)
#省略
nvmを使用してnpm(node package manager)とnodeをインストール
次はnvmを使用して、npmとnodeをインストールしていきます。
以下のコマンドでインストールできます。
安定版:nvm install stable
最新版:nvm install --lts
今回は、安定版を入れていきましょう。
[vagrant@local-docker ~]$ nvm install stable
Downloading and installing node v14.1.0...
Downloading https://nodejs.org/dist/v14.1.0/node-v14.1.0-linux-x64.tar.xz...
インストールが終わったら、バージョンを確認します。
※2020年5月現在は安定版インストールで以下のバージョンがインストールされました。
[vagrant@local-docker ~]$ node -v
v14.1.0
[vagrant@local-docker ~]$ npm -v
6.14.4
これでnode, npmのインストールは終了です。
Laravelプロジェクト内でnpmを使えるようにする
ここからが重要です。
冒頭で説明したように、VirtualBoxの共有フォルダ内でnpm installするとエラーが出てしまいます。
したがって、共有フォルダの外でディレクトリを作成し、それを共有フォルダ内のnode_modulesディレクトリと結びつけることでこれを解消します。
実際にやってみましょう。
共有フォルダの外でnode_modulesをマウント
まずは現在の位置を確認。
※今回は~/docksが共有フォルダに設定されています。
[vagrant@local-docker ~]$ pwd
/home/vagrant
[vagrant@local-docker ~]$ ls
docks
docksが共有フォルダなので、その外に新しいディレクトリを作成。
[vagrant@local-docker ~]$ mkdir vagrant_node_modules
[vagrant@local-docker ~]$ ls
docks vagrant_node_modules
作成したvagrant_node_modulesをlaravelプロジェクト内のnode_modulesと結びつけていく。
#Laravelのプロジェクトまで移動
[vagrant@local-docker ~]$ cd docks/docker-laravel/laravel-app/
#プロジェクト配下にnode_modulesを作成
[vagrant@local-docker laravel-app]$ mkdir node_modules
#ホームディレクトリに戻って、作成した2つを結びつける。
[vagrant@local-docker ~]$ sudo mount --bind ~/vagrant_node_modules ~/docks/docker-laravel/laravel-app/node_modules
※コマンド上の~/vagrant_node_modulesと~/docks/docker-laravel/laravel-app/node_modulesの間はスペースが必要です。
動作確認
作成した~/vagrant_node_modulesと~/docks/docker-laravel/laravel-app/node_modulesがマウントできているかを確認していきます。
どちらか一方で適当なファイルを作成し、それがもう一方に反映されていれば、成功です。
[vagrant@local-docker ~]$ cd vagrant_node_modules/
[vagrant@local-docker vagrant_node_modules]$ touch test.txt
[vagrant@local-docker vagrant_node_modules]$ cd ~/docks/docker-laravel/laravel-app/node_modules
[vagrant@local-docker node_modules]$ ls
test.txt
[vagrant@local-docker node_modules]$ rm test.txt
npm installして実行してみる
以下のコマンドで、npmをインストールし、実行してみましょう。
[vagrant@local-docker ~]$ cd ~/docks/docker-laravel/laravel-app/
[vagrant@local-docker laravel-app]$ npm install
[vagrant@local-docker laravel-app]$ npm run watch-poll
エラーが出ずに、実行されていれば以下のような表示がでれば成功です。
DONE Compiled successfully in 6142ms
※ctrl+Cで抜けられます。
プロビジョニングでマウントを自動化する
いままでの手順で、Vagrant上のlaravelプロジェクト内で、npmコマンドが使えるようになりました。
しかし、このままではvagrant upするたびにマウントをし直さなければいけないので、自動でマウントするように設定をしていきます。
今回はVagrantfileと同階層にvagrant_init.shとしてプロビジョニングのファイルを用意してあります。
その最後に、以下のコマンドを追記します。
#省略
sudo mount --bind ~/vagrant_node_modules ~/docks/docker-laravel/laravel-app/node_modules
追記ができたら以下のコマンドで設定が反映されているか確認します。
- vagrant provision
- 起動中のマシンで行う場合
- vagrant reload --provision
- 再起動し行う場合
処理が終わったら、再度Vagrant上のlaravelプロジェクト内で、npm run watch-pollとしてコンパイルが正常に行われれば成功です。
おつかれさまでした。
最後に
この方法の他にも、ローカルにnpmをインストールする方法もあります。
しかし、その場合だとnpm run watchをするたびに、vagrantから抜けてローカルで実行する必要があり面倒だったので今回の方法をまとめてみました。
参考記事: