Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Install node_modules to vendor

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.

like image 307
mozg Avatar asked Jan 04 '15 10:01

mozg


2 Answers

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?

  1. 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.

  2. Then npm installs all the dependencies.

  3. 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.

like image 157
Hayko Koryun Avatar answered Sep 28 '22 08:09

Hayko Koryun


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.

like image 36
Matthew Bakaitis Avatar answered Sep 28 '22 08:09

Matthew Bakaitis