How can I install npm modules locally for each project to vendor/node_modules
and make package.json
file see them.
I don't want to move package.json to vendor folder
I have bower and in .bowerrc
I specify the bower_components
path - that is super easy.
How can I do that with npm ?
I`ve read the docs, npmrc docs, some questions here, googled, wasted more than an hour - still no luck. This is ridiculously hard for such an easy task.
I don't care about minuses, just tell me how to do that finally.
Frustrated by the fact that there seems to be no built in way to install into a node_modules
folder in an arbitrary subfolder, I came up with a sneaky solution using the two following scripts:
preinstall.js
var fs = require("fs");
try
{
fs.mkdirSync("./app/node_modules/");
}
catch(e)
{
}
try
{
if(process.platform.indexOf("win32") !== -1)
{
fs.symlinkSync("./app/node_modules/","./node_modules/","junction");
}
else
{
fs.symlinkSync("./app/node_modules/","./node_modules","dir");
}
}
catch(e){}
postinstall.js
var fs = require("fs");
try
{
if(process.platform.indexOf("win32") !== -1)
{
fs.unlinkSync("./node_modules/");
}
else
{
fs.unlinkSync("./node_modules");
}
}
catch(e){}
All you need to do is use them in your package.json
file by adding them to the scripts
option:
"scripts": {
"preinstall": "node preinstall.js",
"postinstall": "node postinstall.js"
},
So, the big question is: what does it do?
Well, when you call npm install
the preinstall.js
script fires which creates a node_modules
in the subfolder you want. Then it creates a symlink
or (shortcut
in Windows) from the node_modules
that npm
expects to the real node_modules
.
Then npm
installs all the dependencies.
Finally, once all the dependencies are installed, the postinstall.js
script fires which removes the symlink
!
Here's a handy gist with all that you need.
You cannot, not using built-in npm functionality.
This discussion on the npm github repository covers the issue. It's also being addressed in this answer which is part of their FAQ.
You can still do the installs "manually" by copying modules into your /vendor
directory and then calling them using the require("./vendor/whatever")
syntax...but that means each require
needs to use your new custom location. There are a few ways you could handle this but they all mean you are doing extra work in your source to accomodate the custom location.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With