Can I put the npm node_modules directory outside of my project - node.js

Can I put the node_modules directory outside my project just the way maven does with its dependencies?

Sort of. The node_modules directory is not actually a feature of npm but a feature of node.js.
How node.js uses node_modules.
When you require a module node.js will search for a node_modules directory from the current directory upwards. That means if it can't find one in the current directory (which may actually be a subdirectory of your project instead of your project directory) it will look for it in the parent directory then the parent's parent all the way to your root directory.
For example, you can have a project structure like this:
/node_modules <-------------------- modules available to all projects
/code
/project_A
/node_modules <------ modules available to project A
/lib
/node_modules <-- modules available to the lib directory
/project_B
/node_modules <------ modules available to project B
This way you can have some modules shared by multiple projects and some modules that are project specific and even some modules that are only available to some files in your project.
How npm handles node_modules
Note however that npm has only one interpretation of node_modules. It only manages node_modules in your project directory. Specifically the directory that contains the package.json file.
So yes, you can do it but npm won't understand what you are doing and your package.json will contain incomplete dependencies. I wouldn't recommend doing this with projects involving multiple developers because it will look more like a misconfigured development environment - basically others will think this is a bug. However I personally have used such structures for personal projects where I don't care about my package.json file.

As mention in this question Don't do it. Let NPM work the way it's designed to. However, to save space, you can delete the node_modules folder on projects that are currently dormant, and recreate it with a single shot of npm install when you switch back to them.
It is an issue if the plugin declares to install the modules in a configurable directory. Therefore I suggest to fix the documentation, it gives false hopes.
Please see npm docs, as this is the default behaviour of npm. Not a frontend-maven-plugin issue.

Yes you can, but you should try to avoid doing so.
npm install will always install the modules within node_modules folder in your parent working directory.
Whenever you install a module using npm install -g module_name, it installs modules globally outside your project directory which can be also used in other projects, normally some dev dependencies are installed globally which helps you in development purpose.
An example would be
npm install -g #angular/cli , doing this once will enable you to use ng commands to build ,test other angular projects as well.
Other than this,it would be ideal if all the node_modules which are required for your project would stay in the working directory of your project.
Installing anything globally outside your project is considered bad practice as different projects may depend on different versions of the same node_module.Installing node_modules locally within the project directory allows different projects to have different versions of same node_module.

Related

Should node_modules be in User folder or project folders?

I am a total Javascript newbie aiming to configure my Mac nicely for development.
NPM is installed.
I notice that folder node_modules exists in my Users/MyName directory.
I think this is a result of having either installed Node/NPM or specifically run npm install airtable the other day, which I did at the time in Users/MyName.
When I npm uninstall airtable, it removes airtable and its dependency folders from nodule_modules, leaving the following: #types and package-lock.json (hidden).
If I cd to new project-specific directory Users/MyName/Projects/Code/myusername/airtable-test and run npm install airtable from there, I expected the packages may get installed in that folder. However, again, they get installed up at Users/MyName/node_modules.
In both cases, .package-lock.json (non-hidden) and package.json are in Users/MyName, which seems messy to me. (I haven't done anything non-standard in install).
Is this the way things should be?
Attempts to solve:
I seem to read, including from questions on Stackoverflow, that storing modules at Users/MyName/node_modules is effectively storing them globally, accessible to any app, and such that projects don't have to get committed to server with all dependencies in tow - the idea being that, after you deploy your app, you then run npm install whilst in its folder, prompting it to install all dependencies.
Is this right? Should I be looking at storing all dependency modules in a project folder, or above and outside of it?
(If the answer to this question is opinion-based, I wasn't aware of that).
Here is what I believe is happening. You have your package.json in folder Users/MyName and you are running npm install in Users/MyName/Projects/Code/myusername/airtable-test. But the problem is you do not have package.json file in the folder Users/MyName/Projects/Code/myusername/airtable-test. So npm goes up in the directory to find the package.json and it found it in Users/MyName so it is installing the package there.
This is happening because the way npm identifies a project is by looking for package.json. If it does not find it in current directory than it assumes that you must be inside some sub directory of the project and start searching upwards in the folder hierarchy to find the package.json.
solution
Do npm init in the folder Users/MyName/Projects/Code/myusername/airtable-test. This will initialize the folder as a npm package (by creating package.json).

Please help clarifying the structure - nodejs/npm

Currently I've installed Node.js and npm on my Windows 10 and first package called hotkeys-js. I have no idea why I have least two node_modules directories within distinct paths, i.e.:
one in
C:\Program Files\nodejs\node_modules\npm
which I do consider as parent working directory, correct if I am wrong?
second which is most questionable for me:
C:\Users\<*whateverUsernameWouldBe*>\node_modules\first_npm
also the structure within first_npm as:
|- node_modules
|- index.js
|- package.json
|- package-lock
Why do I have this separate directory at all? Is it local/global? What is the purpose of this one?
The node_modules folder under Program Files contains the npm modules installed as part of the nodejs installation package, and the npm modules you install with npm install -g whatever for common, global, use on your machine.
The node_modules folder in your project folder contains the npm modules you installed as part of your project.
Don't mess with the one under Program Files except via npm install -g and npm uninstall -g commands. At least until you get a little more proficient with this stuff.
Your life might be slightly easier if you create your own nodejs / npm projects in a folder called C:\Users\<*whateverUsernameWouldBe*>\myNodeProjects or something like that, rather than a folder called C:\Users\<*whateverUsernameWouldBe*>\node_modules. Folders named node_modules are generally maintained by npm. When you create one that isn't, you can confuse yourself. Ask me how I know this sometime.

Is it possible to avoid local node_modules in js projects?

I am exploring nodejs and js frameworks. I noticed that when I create a project, for example with vue
vue init webpack my-project
I get a HUGE directory named node_modules containing a lot of things not related to my project. Newbie in this field my only wish is to gitignore this folder or better, put it somewhere else.
Is it common to have local modules to a project? Is there a way to install all these dependencies globally or in a dedicated environment (e.g Python virtualenv)?
The directory does contain libraries that are required by your project - and their dependencies. From my experience, the dependencies of the libraries I'm using are about 3/4 of the folder size.
You can install a library globally using the -g switch of npm, I'm not sure if vue has similar option. But this is not recommended - the point of installing libraries with your project is that the project will remember which libraries belong to it, those are saved in package.json.
You could copy the node_modules directory to the root of your hard-drive and merge it with other node_modules directories, but you're risking that you'll mix different library versions that way, so this is not recommended.
Unless you're running low on free space, just leave it be. Remember to add the node_modules to .gitignore if you're using git.
In short, node_modules is a place where all your project dependencies are stored. And allows you to use these dependencies in the code if you want to and allows for the modules itself to have it own dependencies if any.
And it is very common or rather always the case when a local node_modules folder is created.
You can install dependencies globally by doing npm install -g module_name command via your CLI. But these may cause the issue if the global paths are not configured properly.Also, it is not advisable to keep all the required dependencies by an application in global context.
If you do not want some dependencies to be part of your production environment you can install them as dev dependencies via npm install--save-dev module_name command. These(normal & dev dependencies) will be installed when a developer clones your project and run npm install locally to run the project and run tests. But to ignore these from being installed on production you can execute npm install --production command, this will make sure that only dependencies required for your code to run will be installed in the node_modules folder.

Can I use one node_module folder for all angular2/4 projects

I am learning Angular and each time it takes like 5 minutes to create a new project because of 100MB folder "node_modules" which CLI creates. And the files in this folder are always the same (unless you add some dependencies which I never do). Is there a way to use one node_modules folder for every project?
Have a look in to https://yarnpkg.com/blog/2017/08/02/introducing-workspaces/
Yarn Workspaces is a feature that allows users to install dependencies
from multiple package.json files in subfolders of a single root
package.json file, all in one go.
Making Workspaces native to Yarn enables faster, lighter installation
by preventing package duplication across Workspaces. Yarn can also
create symlinks between Workspaces that depend on each other, and will
ensure the consistency and correctness of all directories.
npm install -g yarn
You can install all dependencies globally or create a symlink from one place to every project.
BUT it is bad practice, correct way is to use separate node_modules for each project, even if you are using same packages. Once you will need use different versions of same package in different projects and common node_modules will cause a lot headache.
Try to use npm cache and npm install --prefer-offline if you just want to install package faster and don't care about version very match. I didn't use it but believe it should work.
Only packages installed by node (npm install) can be in the node_modules folder. This is because, if someone wants to install your project, instead of downloading the whole project with the node_modules included. They type npm install.
Based on the packag.json the node_modules will now be downloaded to the node_modules folder.
So you can put angular in the node_modules folder if it is an npm package. No you cannot put your own files in this folder.
So you can just copy your package.json to every project and run npm install. Then all the node_modules will be the same.

Using NPM & gruntjs build system

I am new to Node.js echo system and trying to set up a build system for JavaScript application development. I have some questions that I can't find answers to.
From this blog post, it is clear that you should install all the project specific node modules locally.
Now, I am installing the entire grunt module locally in my project directory. I get the following directory structure...
my_project/
lib/
utils/
underscore.js
... other project files ...
node_modules/
.bin/
grunt -> ../grunt/bin/grunt*
grunt/
node_modules/
bin/
dev/
docs/
lib/
test/
tasks/
grunt.js
package.json
... others ...
Note that there are TWO node_modules directories. One in my project and other inside the grunt module.
Q: Why are there multiple node_modules directories at different levels? Can someone explain me how the directory structure works?
Q: If I install another module, will it also have its own node_modules directory?
Q: If I go within my_project/lib/utils and then run the command npm install <some_module>, will that module be installed only for that directory or for the entire project? If the latter, then how does NPM/Node figure out the project root?
Please explain anything else I might be missing here.
Every project in the npm registry can be thought of a self-contained module (specifically, a CommonJS module) that has source code and project metadata defined in a package.json file in the root directory of that project.
When you type npm install (or just npm i) in a directory with a package.json file, npm reads the collection of dependencies defined in package.json in your project's root directory and installs those packages in the node_modules directory.
So what's with the nested node_modules directories? npm install is recursive. If project A requires B and B requires C, you'd see this directory structure:
A/
A/node_modules
A/node_modules/B
A/node_modules/B/node_modules
A/node_modules/B/node_modules/C
In your case, when you add grunt to dependencies in the my_project/package.json file, that dependency will get added to its own directory: my_project/node_modules/grunt. But grunt has a lot of dependencies, and those dependencies have dependencies. So you'll see many nested node_modules directories.
For your third question, see the algorithm section on this page: https://npmjs.org/doc/install.html -- it describes how npm install searches for dependencies.
There's also some more information about global vs local dependencies in npm here.

Resources