node modules of modules install in unwanted spot - node.js

Hello and thanks for reading,
Historically, when I ran the command:
npm install module
Module would install in the node_modules dir of the current working directory. This still happens, however, the modules that the module use, is now installing alongside the original module, so that my node_modules dir might look like:
./node_modules/module/
./node_modules/module-of-that-module/
When it used to look like:
./node_modules/module/node_modules/module-of-that-module/
I suppose it might boil down to preference, but I don't really like the sub-modules installing alongside the main module I was trying to install, as my main node_modules directory became cluttered with hundreds of random modules fast. Also it seems kind of strange for the structure to be this way if the modules of modules need different versions.
Can anyone please explain what changed here? And how I might change it back? I tried to find a solution prior to writing this, but it's unclear to me how to search around this issue or what category it falls under.

Related

React unable to find modules

I run into this problem pretty frequently while developing react applications. The latest is hwid. I am using yarn to manage dependencies.
I added the module using
yarn add hwid
It added it to the package.json file and gave me no errors. When I run the application, it says it is unable to find the module. The module is there in node_modules and everything seems to be correct and in place. So I tried deleting node_modules and running yarn install. I've done this several times. I tried force cleaning the npm cache. I have run yarn remove and yarn add several times.
I am using the WebStorm IDE. It gives me no errors, and in fact, if I let it resolve the import, it finds it just fine. This seems to only happen to me in react projects. I think, but I'm not sure, that it is usually typescript modules that give me problems.
Is there a magic bullet for this? The module is a pretty critical part of my app, so if I can't resolve it using node and react's import system, I'm going to have to just copy the files into my project. I would really rather not do that for obvious reasons.
Any help is appreciated.
If it's about typescript modules, have you tries also installing types of that modulea?
E.g.yarn add #types/hwid

System-wide deduplication of identical node modules

I'm working on a Javascript project, and as it so happens one of my dependencies pulls in puppeteer, which in turn downloads a whole copy of Chromium into my node_modules. My larger project is split into multiple Javascript packages, so I end up with multiple identical copies of Chromium among other stuff.
Is there a way to deduplicate these packages system wide? Note, npm dedupe seems to do something completely different to what I want.
I imagine there would be a module repository in my home directory which contains every package I need (in every version needed), and then in the local node_modules directories would contain only symlinks to the repository. This seems like an incredibly obvious optimisation, but I can't find any way to do it in npm. If not in npm, is it maybe possible in yarn?
As an added complication, this should also work on Windows (where symbolic link support has historically been not so good).
It seems the following command does what I want:
npm config set link -g
Then delete node_modules, and do npm install again. It should be much smaller now.
The documentation says:
If true, then local installs will link if there is a suitable globally installed package.
Note that this means that local installs can cause things to be installed into the global space at the same time. The link is only done if one of the two conditions are met:
The package is not already installed globally, or
the globally installed version is identical to the version that is being installed locally.
I am not sure if this has any negative side-effects - for example clobbering the global namespace with commands I don't want. For now, it seems to work fine.

Finding node module from different directory?

Always feel stupid asking here because people are always confused with my questions, or I have a dumb problem, but, I'm working on a program in node.js and the text editor I'm using (NP++) doesn't seem to like to save files in the system32 directoy, (The directory where my modules are), and that is where my script is as well. (So I have .../.../node_modules/(modules) and .../.../node_modules/script.js) this becomes a pain when I want to edit the script, I have to clone the script to my desktop, then edit it, then overwrite the one in the node_modules directory. I tried saving the script to my desktop and running it, but it just gives me an error of module not found. (In my script I have the modules as var example = require('example.js')) Is there any way I can get it to get the modules from the node_modules directory, while keeping the script file somewhere easily accessible and editable? (i.e desktop?) (Sorry if this is confusing, not the best at these kind of things)
I'm not 100% sure that this is what's happening because I haven't used npm on Windows, but it sounds to me like you're installing your dependencies globally using npm -g. The more proper way to use Node is to install your dependencies locally, using npm without the -g flag. That way your dependencies get installed in your current working directory.
For example, let's say you've saved your project in a directory on your Desktop, and your script uses require("lodash"). If you cd to your directory and run npm install lodash, then the lodash module will be available to your script.

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.

Installation of gulp through node.js's npm breaks windows

I want to use gulp on my windows machine and it actually works pretty fine, unless I try to use the created files (like pushing to github or deleting). Then it breaks, because the filepaths are too long and it seems to be a fairly common problem. https://github.com/joyent/node/issues/6960#issuecomment-45569604
I understand that the problem arises through npm's nested directories, which extend the maximal char count for Windows directories, but in my understanding there is not any solution yet.
As I see it right now I have three options:
Try to reduce the chars of npm's directories, by changing the default from 'node_modules' to 'n_m' and hope that problem ist postponed. Like suggested here:
https://github.com/joyent/node/issues/6960#issuecomment-45569604
Then it is my question, how exactly do I change the default 'node_modules' directory name?
Change my development environment to Ubuntu, which is frankly a solution I dislike, because I've never used Ubuntu.
Stop using gulp overall.
So, how do I change the default 'node_modules' directory created through npm or what solution do you actually suggest?
There is one more tricky option.
Main problem is that gulp has a lot of nested dependencies and it creates very long nested file pathes.
But if you install some of npm modules that gulp requires in your main node_modules directory gulp will not download them as nested.
Currently you have something similar to (this may be not real path you have but idea is the same):
\node_modules\gulp\node_modules\lodash.bind\node_modules\lodash._createwrapper...
If you will add "lodash.bind" module to your project's package.json as dependency it will be installed in one level with gulp and not as gulp's dependency
\node_modules\gulp
\node_modules\lodash.bind\node_modules\lodash._createwrapper
And this will shorter all urls. You will need to fix only one or two with the longest pathes and it will work.
In my project it was enough to add this dependencies: “lodash.createcallback” and “lodash.bind” to package.json to fix everything.
Take in mind that befor doing this you probably would need to clear current node_modules folder. If you are not able to do that because off too long url you can create symbolic link to temporary short file path and delete it.

Resources