🎃

【小技】Vagrantの共有フォルダ上で'npm install'が動かない場合の対処法

2020/10/20に公開

どうも、スウェーデンでITエンジニアをしているあめぞう(@amezousan)です。

今回はVagrantの共有フォルダ上でnpm installが動かない場合の対処法について書きます。検証に利用した環境は以下の通りです。

テスト環境

(2020-10-20 執筆当時)

  • ホストOS「macOS Catalina v10.15.7」
  • ゲストOSbento/ubuntu-18.04(Guest) v202010.14.0」
  • ソフトウェア
    item version
    node 12.19.0
    npm 6.14.8
    yarn 1.22.5

何が問題なのか

Vagrantの共有フォルダ上で、npm installを実行すると例えば以下のようなエラーが出ます。

ちなみに僕の環境では共有フォルダ以外は普通に実行できます。

$ npm install mongodb
npm WARN test@1.0.0 No description
npm WARN test@1.0.0 No repository field.

npm ERR! code ENOENT
npm ERR! syscall open
npm ERR! path /home/vagrant/shared-folder/test/node_modules/string_decoder/node_modules/safe-buffer/package.json.1130074357
npm ERR! errno -2
npm ERR! enoent ENOENT: no such file or directory, open '/home/vagrant/shared-folder/test/node_modules/string_decoder/node_modules/safe-buffer/package.json.1130074357'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent

npm ERR! A complete log of this run can be found in:
npm ERR!     /home/vagrant/.npm/_logs/2020-10-20T08_54_18_215Z-debug.log

簡単に言うとnpm install時にパッケージが保存されるディレクトリnode_modulesが見つからない、と言うもの。

そしてこの問題は複数の環境で報告が上がっておりgithub issueを探すと似た症状で困ってる方を発見できます。

Vagrantの環境によっては現在も同様の症状が出ています。

解決策1: VirtualBoxから共有フォルダでシンボリックリンクを有効化する

恐らくこの方法が1番汎用的かと思います。 -> 嘘付きました。この方式はWindowsのみ有効のようです。(WindowsではSymlinkが使えないからこれを有効にする必要あり?)

手元にWindowsがないので分からないのですが元記事を見る限りyarnのみ有効なのかも?

config.vm.provider :virtualbox do |vb|
  vb.customize ["setextradata", :id, "VBoxInternal2/SharedFoldersEnableSymlinksCreate/.","1"]
end

Create以下のファイル指定はは自分の環境に合わせて変えてください。

参考: Windowsホスト上のVagrantのシンボリックリンクフォルダでyarn installできない問題の解決

解決策2: yarnを使う

追記(2020-10-21): この方法が1番手軽で良いです。

npmの代わりにyarnを使うと上手くいくケースがあります。ただし環境によっては動かない可能性があります。(主にWindowsのみ?)

その場合、解決策1でシムリンクを作成させるかあるいは「--no-bin-links」オプションを使う方法があります。

yarn install --link-duplicates
Create hardlinks to the repeated modules in node_modules.

https://classic.yarnpkg.com/en/docs/cli/install/#toc-yarn-install-no-bin-links

解決策3: シムリンクを手動で作成する

上記、npm - issueのコメントで以下の回避策が紹介されています。

  1. どこでも良いので新規ディレクトリを作成
  2. npm installを実行するディレクトリに移動
  3. 同ディレクトリで(1)で作成したフォルダに対しnode_modulesと言う名前のシムリンクを作成
  4. 同ディレクトリでnpm installを実行
  • コマンド例
$ mkdir ~/tmp_node_modules
$ cd <your-path-to>/npm_project/
npm_project$ ln -s ~/tmp_node_modules ./node_modules
npm_project$ npm install mongodb

ただしこの方法には1つ問題があります。

それはプロジェクトごとにnpmライブラリを変更する場合その度に新しいディレクトリを作成&シムリンクを作成する必要があると言うこと。

この問題は実際に開発していくと分かりますが非常に面倒で厄介なので解決策2をオススメします。

解決策4: ホストOSでインストールする

共有フォルダ上でホストOS側からインストールすることでこの問題は解決します。インストールされたソフトウェアバージョンによる思わぬトラブルを避けるため、ホスト/ゲストOS共にバージョンがなるべく近いものを設定するなどの配慮も必要になってきます。

どうしてもnpmを使わないといけない時にこの方法は有効ですね!

最後に

いかがでしたでしょうか。まとめると以下の方法が、Vagrantでnpmパッケージを管理する上のベストな施策(執筆時点)なのかな、と考えてます。

  1. 基本は 解決策1:yarnを使う
  2. どうしてもnpmを使う必要がある場合は解決策4: ホストOSでインストールを併用する

複数人で同じ開発環境を揃える際にVagrantは非常に強力なツールです。違うパソコンから同じような環境をゼロから手軽に構築することが可能になります。

ただ仮想環境と言うこともあり、ホストOS上で普通に動作するものがゲストOSで動かない、と言う問題も度々起こるため取り扱いには注意です。

今回はこれにて。ではまた、Vi ses!

Discussion