I created a website for non-profit Matsuri Japon, and recently I made the decision to start recruiting/training volunteers for the website development. Therefore the next logical step for me was to setup Vagrant. The default Vagrant configuration uses VirtualBox, but I needed a Hyper-V VM provider for myself since I personally use Hyper-V. Oh and most of the volunteers will be using Windows.

And comes the nasty part. By default you would have a /vagrant shared folder mapping to your source code (on the host). Did I mention we use node.js? Well run npm install and watch the console throwing shit back at you. This is a pretty common issue with npm and Windows due to npm’s stupidly large amount of nested directories and Window’s 255 character limit on file paths. Between a rock and a hard place.

Most websites only provide a solution for the more common VirtualBox provider and I’ll put it up here for reference:

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

But what about Hyper-V? Most online “solutions” only go as far as suggest setting override.vm.synced_folder ".", "/vagrant", type: "smb" which does absolutely nothing to solve the npm issue and is actually not even remotely related to the problem at hand. Some GitHub Issues thread suggest running npm install --no-bin-links and a prayer. Now we were getting somewhere, but notice the prayer part. Can we do better?

Turns out what worked in an acceptable fashion for me was to work things in the other direction. At the beginning I wanted to have the VM launch the node.js app from the /vagrant shared folder, npm install and all. The more elegant solution I found was to symlink the shared folder to the VM’s home directory. Or was it the other way around, I tend to get the target/targeted terminology mixed up. The following code explains it better:

# Inside Vagrant provisioning script
mkdir /home/vagrant/node_modules
ln -s /vagrant/* .

Simple. Elegant. The first line creates a real node_modules folder to prevent ln -s from creating a symlink for that folder. Now run npm and node from the VM’s home directory and everything works magically.