prevent scoped node_modules within node_modules - node.js

When I use npm install, there are certain node packages that gets installed that contains nested node modules.
Like this:
-node_modules
-packageA
+js
-node_modules <--- needs to be removed/ignored
+jquery
-packageA-sub1
+js
-node_modules <--- needs to be removed/ignored
+jquery
Is there a way to specify which packages not to include a nested scoped node_module?
In my case, there are packages that are including jquery (packageA and packageA-sub1, sub2, sub3, sub4, etc), and it's messing up my website because I already include jquery in a few of my plugins. The only way to remedy this is by manually deleting the node_module folder inside the packageA folder.
I tried .npmignore but that doesn't seem to work:
packageA/node_modules/
packageA/node_modules
/packageA/node_modules
/packageA/node_modules/
I'm using npm 5.8

You can flatten the node_modules hierarchy, when modules share dependencies with the same version, using npm dedupe
The documentation describes npm dedupe as follows:
Searches the local package tree and attempts to simplify
the overall structure by moving dependencies further up the tree,
where they can be more effectively shared by multiple dependent
packages.

Related

Are all packages also modules in Node?

I've read npm doc, but still couple of my concepts are still unclear which may seem naive, are as follows:
Q1.
A package is a file or directory that is described by a package.json
file.
What do they meant by "described by a package.json file"? Any example to understand easily?
Q2.
Condition to be a package
A package is a file or directory that is described by a package.json
file.
Condition to be a module
To be loaded by the Node.js require() function, a module must be one
of the following:
A folder with a package.json file containing a "main" field.
A folder with an index.js file in it.
A JavaScript file.
Note: Since modules are not required to have a package.json file, not
all modules are packages. Only modules that have a package.json file
are also packages.
So, as per the Note, shouldn't it also implies that all packages are also modules as all packages have package.json files?
A module is anything that can be loaded with require() and does something useful. It can be a single file. It does not need to have a package.json associated with it. In fact, many locally developed "modules" do not. You can have many modules in the same directory.
A package is a set of code designed for easy distribution. If you are using the NPM package manager, then an NPM package will contain a package.json file that has a bunch of meta data about the package, including things like dependencies on other modules, author info, repository info, info on how to test the module, info on which file is the startup file for the module, etc...
FYI, NPM is not the only package manager so it's not the only way of doing things, but for node.js development it is certainly the most widely used and it offers a central repository that makes it easy the "publish" packages for wide and simple distribution.
Are all packages also modules in Node?
I suppose it's possible to distribute something other than runnable code in a package, but the primary use of an NPM package is to distribute modules.
Here's an example of destributing static data rather than code: JSON Data Node Modules Part 1: Using NPM to Store and Distribute Static Data.

Can I create an npm package that sets up another npm package?

I want to create an npm package that would be installed globally, with a binary to call. Calling that binary would set up the initial files for a new project, like your standard folders, standard license and layouts, a package.json with your common dependencies. Then you could call npm install to actually set up that project.
Like the Express application generator, or like rails new does in Ruby. The usage would be like
mkdir new_project
cd new_project
myCoolGenerator new
npm install
But I'm confused about how I'd implement this. The simple approach, which I'm doing now, is to create the standard vanilla folder, ship it with the generator package, and then just have the main binary use ncp to copy that folder into wherever the caller currently is.
My problem there is that I don't know how I can access the folder included in the globally-installed package to copy over. And additionally, npm lets you specify a files array in your package.json to specify files included with the package, but it's apparently hardwired to ignore package.json from that.
What's the recommended procedure for this sort of thing?

Access node_modules from another folder

Recently started working with Gulp and I can't figure out is it really necessary to have a copy of node_modules directly in folder with current project?
E.g. I have this structure:
mysite
└─builder
└──node_modules
└─work
└─work2
How can I access node_modules in folder 'builder' from folder 'work' or 'work2' without copying it? It is quite large, about 100mb, and seems to me it has no sense to have a copy of it for every new project.
I tried this line export NODE_PATH='D:\OpenServer\domains\mysite\build' in file package.json and then tried command gulp but it replied[10:24:27] Local gulp not found in d:\OpenServer\domains\mysite\work
[10:24:27] Try running: npm install gulp
Short answer
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.
Justification
Even if you share your node_modules, you'll probably have redundancies in it anyway. What will you do about them next ?
It is the essence of NPM to replicate modules per project. If you dig into the node_modules folder tree, you may notice that it can even contain several replications of a same library under one given dependencies tree. Say you requested two modules explicitely, and both these modules themselves pulled a dependency that takes care of a lot of things, and is therefore called lib_DADDYMUMMY :
node_modules
+ a_module_you_use v0.5
+ lib_DADDYMUMMY v0.1 (pulled as a dependency of this module)
+ another_module_that_you_requested v0.3
+ lib_DADDYMUMMY v0.1 (again ! pulled as a dependency of this other module)
This comes in handy when your two module start needing different versions of lib_DADDYMUMMY. This comes in handy when you maintain long-lived projects ! And hell knows that in the JavaScript world, with fast changing APIs, you can consider most any decent project as long-lived. :)
One could imagine having all dependencies being shared by everyone, living in a flat structure, with several versions of a library living next to each other and every one finding what he needs there. That repository could be called, say, .m2. But that's just not the way NPM works unfortunately.
NPM considers that storage space is cheap. That's its price for helping you manage versions in dependencies, dependencies of dependencies, and dependencies of dependencies of dependencies. I consider that it's an affordable price for taking care of the dirty jobs the day when work and work2, as their lives go on, take diverging maintenance paths. I wouldn't try getting in its way by forcing a half-Maven-like folder model.
Maybe you should put your package.json into your root directory(mysite/package.json),
then try to install node_modules on the root.
In addition, you write gulpfile on the same dir.
eg.
mysite
|- package.json
|- node_modules
|- gulpfile.js
└─builder
└─work
└─work2
However, I recommend that you write one single gulpfile for each project.
One problem why you shouldn't do this is because of versioning. If your modules require different versions of the same package, you're going to run into problems. One package is going to win, and it might break another package.
Further, you get into the problem of having to merge the dependency lists in some way - meaning, you'll have to get the dependencies from work/package.json, work2/package.json, etc. and then install all of them at once.
Merging node_modules/ won't solve your problem, either - believe me, don't try.
Paste the node_modules folder inside your mySite directory.
All npm packages such as gulp will work in your work or work2 directory.
But, now(your folder structure) work folders can't find node_modules in their parent directory.

keep node_modules outside source tree in development (not production)

I prefer to keep all generated files and dependencies outside my source tree while I work on it.
npm and grunt make that difficult: npm will never allow moving local node_modules, so I have to use --global and --prefix. But grunt does not support such a scheme, apparently.
How can I achieve my objective given the above constraints?
So, if I have a project:
foo/
.git/
src/
gruntfile.js
package.json
I want no extra files in my tree, specifically, node_modules. (Also bower_components and build etc but this is about npm.) This directory should remain untouched while I am working on it and running it. That is all.
Apparently npm link is supposed to do this, but when I tried it still installed all the dependencies in ./node_modules. Any other invocation I cannot fathom; the docs are not clear.
A related suggestion was to use another directory with symlink to my gruntfile or package.json, but grunt just resolved the symlink and continued to work in my original directory!
So far the closest I have come is to link to e.g. ~/.cache/foo/node_modules from my project. Although it achieves keeping the deps out of my tree, I still have this link cluttering my workspace.
I want to know if there is a better way. Will some combination of npm install, npm link, ln, ~/.cache, NODE_PATH and PWD allow me to run my project, from my source tree, and keep it clean of all non-source artefacts?
Swimming against standards is a Very Bad Idea ®.
What you can (and should) do is add node_modules/ to your .gitignore (or whatever ignore file you have for your given source control system) so you don't version these files.
Also, you can use a directory like src/ to organize your code and "shelter" it from the mandatory configuration files (package.json, Gruntfile.coffee, etc).

is good practice to include my modules in node_modules for make require search easy,if not why not?

is good practice to include my modules in node_modules for make require search easy,if not why not?
Explanation:
In node.js cms calipso( https://github.com/cliftonc/calipso)
their modules not inside node_modules: then the include the modules without auto option:
calipso = require(path.join(rootpath, 'lib/calipso'));
vs if it was inside node_modules:
calipso = require('calipso');
node_modules is typically ignored in the version control (GIT, etc) and most of the developers assume that this folder contains only packages listed in the package.json. I can imagine the approach on updating the modules just by removing this folder completely and executing npm install. Considering these I would rather say that keeping own modules in node_modules is not consistent with the node.js workflow.
Update: this is assuming that "my modules" is actually just a set of files. If your modules are "npm" modules, that can be restored by executing "npm install" then this is completely fine to keep them in node_modules.

Resources