Why does one npm Module delete other npm modules? - node.js

This whole "nvm" - "npm" fiasco is a disgusting mess. For one thing, they should have a big flashing red banner at the top of the npm Web-Site that says, "If you intend to do ANYTHING with Node.js, you better decide right now to get rid of the spaces from your folder names." I never saw any warnings to sanitize my pathnames. And it didn't help that I tried to go back later and delete those blank spaces out of the path. As far as npm is concerned, I committed a capital offense with those blank spaces, and I have paid dearly for that error.
For all I know, maybe I am still paying. Why is it that when you install "nodemon" as a development dependency npm install --save-dev nodemon ( as opposed to just installing it globally in a totally separate folder npm install -g nodemon ) why does it delete "npm"? Oh, the npm files are still sitting in the same place that they have always been, but when you go into the Command Prompt and type npm -v the Terminal acts like he never heard of npm ... like you must be speaking in Russian.
OK, so let's use the Node.js installation executable to "RE-install" the npm that has gone on sabbatical ( actually, the *.msi file calls it "repairing" the installation. ) Now, you get your npm back. Great. But now you have a new "npm" folder with hundreds of "node_modules" sitting in a sub-directory of npm. This is what they call repairing?
But your troubles aren't over yet. Let's install the very popular npm module: "dotenv" as a development dependency. This time, the "nodemon" folder ( that you just installed 1 minute ago ) has been deleted, and yes, ( yet again, ) npm has gone fishin'. That is to say, npm -v no longer works, even though the npm files haven't gone anywhere.
I would love to know. How many times am I going to have to re-install npm before I finish writing my first childishly simple Node.js Module?
It's a good thing the npm trash is free. They couldn't afford to give us our money back.

I will probably be crucified for answering my own question, but it is working for me.
Here is the bottom line: Everyone should be able to reasonably expect that when they install a software package, that it is not going to cannibalize other software that they have installed, nor is it going to chew-up their operating system. But that is what was happening to me with this npm trash.
And if you want to know if you are having the same problem, just run this test:
Install npm and Node.js Then, install about 5 more npm modules of your choice.
After the installation is complete, you should immediately UN-install all 5 npm packages, plus Node and npm.
After the installation and Un-installation is finished, you should be left with an empty folder. If the folder has ANYthing left, then your npm modules have been chewing on each other, and spitting out the pieces for you to have to clean up.
That is what was happening to me. And I suspect that whenever you hear someone on YouTube suggesting that you should install Nodemon 'Globally', my guess is that they are having the same problem that I had, but they don't know how to fix it, so they just push Nodemon off into a different folder where it can't destroy the other modules that they have already installed.
But their "solution" is actually not such a bad idea. Why not put EVERY npm module into its own separate folder ? You could sandbox each package, to protect it from other packages that you install later.
To make my solution clear, I will diagram my proposed folder structure. We start by installing npm and Node:
Node
|
|__node_modules
Now, npm wants you to continue installing all other npm packages into the node_modules folder. But you can force npm to put each npm package into a folder that you get to pick, so that the new structure looks like this:
Node-14
|
|
|_____myExpress
| |
| |__node_modules
|
|_____Joi-13
| |
| |__node_modules
|
|
|__node_modules ( should be NODE ONLY ...
nothing else. )
Here is the command that will allow you to achieve the outcome above. In the Command Prompt, you must first Navigate your way into the Node-14 folder shown above. Once you are in that folder, type the following command:
npm install --prefix ./myFolder npm-package
npm will happily create the folder called "myFolder", and then will install the latest version of the "npm-package" that you requested.
And here are a few examples:
npm install --prefix ./myExpress express
npm install --prefix ./NodeMon-dev nodemon
npm install --prefix ./Joi-13 joi#13.1.0
In the examples above, I added the -dev suffix onto the NodeMon folder name, to signify that this package is for Devlopment Purposes.
Also, the 'joi' example shows you how to intentionally install an old version of an npm package, for whatever reason.
There is one caveat to the instructions that I have given. I have said that you can choose whatever folder name you want. That is not 100% true. If you choose a folder name which is the exact same as the package name, then you run into a problem. For example,
npm install --prefix ./passport passport
If you type the command above, then npm will tell you that 'passport' is already installed, and is up to date.
That, of course, is a lie.
Just another example of npm talking trash.
But just to be painfully clear on this issue, in the command below:
npm install --prefix ./Passport passport
The folder name, 'Passport' is NOT exactly the same as the npm Package 'passport' ( because of the Capital Letter ), so that command will work fine.
In the interest of full disclosure, I must admit that there is a price to be paid for using the installation strategy above: when you "require" an npm package in the Node.js software that you are writing, it will no longer be short and sweet:
const express = require('express');
Instead, you are going to have to 'search' for each module individually, because each one is hiding in the sandbox that you placed it in:
const express = require ( '../Node-14/myExpress/node_modules/express' );
Depending on how deep your folder structure goes, it could easily be even worse that what I have shown. In some cases, you might even have to go up 2 or 3 levels from where you are sitting:
const express = require ( '../../../Node-14/myExpress/node_modules/express' );
But in my case, after installing and uninstalling hundreds of npm modules, this was a very small price to pay, for the comfort of knowing that you are not going to be sabotoged by yet another poorly-written pile of trash that acts like a playground bully.
I guess I should also admit that deleting Modules might be a tiny bit more complicated than you are used to.
If you go into the Command Prompt and Navigate to the Node-14 folder ( as you did when you installed the various npm Modules ), and then if you type the customary npm uninstall <npm-package>, you can watch while npm furiously fills up your screen with reams of paths and commands, looking like it is actually doing something.
That, of course, is another lie from npm. In truth, no action was taken.
To uninstall the package, you must Navigate to the Sandbox Folder that you selected, and THEN type the same command. A couple of examples :
Navigate to the "myExpress" folder, and type npm uninstall express
or Navigate to the "Joi-13" folder, and type npm uninstall joi
You will be delighted to find that when npm finishes with the un-install process, the folder will be empty, except for an occasional JSON file. This was a huge change from what I was used to seeing.
Now, you might think that I have gone on and on about npm in this posting, and you might be right. But the truth is, I have left a LOT out of this answer that there is not room to talk about.
For example, I have another mysterious issue going on with my computer that I have posted in a question here:
Running the contributed command: 'code-runner.stop' failed
I seriously doubt that anyone is going to attempt to answer that question, so I will probably have to answer it myself someday. And I predict, that when I finally find out what caused that bizarre issue that I described in the question, that it is going to have something to do with npm. That is my prediction, because I have nothing good to say about npm.

Related

Is npm init needed?

I always thought that you should initialize npm first before installing any packages
npm init --yes
However I found out that I could just go straight to installing packages
npm i example-package
Then the package would be installed and package.json would be created at the same time.
Is there any reason I should be doing npm init first? Is it only required if I want to specify project details?
It is not required. You can install packages without, and everything will work.
npm init can do basically two things:
ask for basic project info to include in packages.json
create a specific type of project (for example React) by using npm init typeofproject
If you just want to use packages and don’t care about naming the project or using a template, just install packages.
npm init is there when you are installing the project very first time.
else you don't need to use npm init for installing any package
Well, kind of a late answer, but as far as I know (correct me if im wrong), one of the features is it gets set up with package.json which includes the dependencies list. That way, NPM can simply install the packages on the list (via the "npm init" if you have a situation that you want to clone the app into another machine), rather than copy pasting the whole project folder.
This isn't a direct answer to the question, but, if sheds some light at some point, why not.

How to get npm to favor local linked dependency over its published install

I've searched through other questions such as this one, but they all seem to be about a local npm link stopping working for another reason than mine. I assume this is a common use-case issue, so if I'm doing something methodically wrong, I'm more than happy to take suggestions on how I should be doing it.
Principally, I have a private npm module that I'm working on called #organisation/module. When working locally, I'll run npm link on it, and use it within my 'host' project as npm link #organisation/module — this all works great with hot-reloading, etc. I'll also import it as import module from '#organisation/module.
However, since I also want to publish my local changes to npm (as #organisation/module) from time to time, for build testing and production code, I need to run npm install #organisation/module on the host project.
This then seems to break the implicit npm link I set up earlier... I assume mainly because they are the same name, and npm favors an install over a link?
When I want to make live, local changes again, the only way I can currently get it to work is via npm uninstall #organisation/module and then to re-link it.
Is there a way to keep the published module installed (in order to avoid careless mistakes, like forgetting to reinstall it for build testing), but always favour the local, linked instance?
Diagram for ref:
Have you tried locally installing with the other method npm provides.
npm install /absolute/path/packageName
I believe this will change your entry in package.json to look like this:
"dependencies" {
...
"packageName": "file:../../path/to/packageName",
...
}
Since npm link creates a symlink in the global folder, while npm install is local to the project npm install takes precedence. You can read about npm link here: https://docs.npmjs.com/cli/link
To avoid this, my suggestion would be to use npm install <path to local> and when you need to use the production code use npm install #organization/module. This would update your node_modules per code basis. Read about npm install here: https://docs.npmjs.com/cli/install
Hope this helps :)
Go to the directory where your local package is located open package.json change the name from original_name to "original_name_local".
write npm link on terminal at the same location.
After this go to your working directory and write npm install <path to local>
Now whereever you're requiring or importing update the name to "original_name_local"
for example if it's require('space-cleaner') then change it to require('space-cleaner_local')
Like this you can have both local as well as production package just change the name wherever required.
Otherwise you can remove package by removing it from package.json and deleting from node_modules.
if local is needed go to local package directory and on terminal write npm link and then on your working directory write npm install ./path/to/package
if production then again delete the package as told above and write npm install package_name

NPM uninstall -g yo, yo still works

I'm a noob at my wits end and have already consulted a couple of friends who know (much) more than me. Sorry if these are dumb questions. Hoping you guys can help.
I think it has to do with some weird NPM pathing issues, but I can't figure them out. npm install -g generator-xxx follows through with success, but when I run Yo, no generators are listed.
Tried npm update -g npm - no dice. Npm remains out of date. This is also true of n and most (but not all? I think?) npm modules.
I tried to start from scratch, followed NPM's advice for a complete fresh start. Reinstalled node from node.js's website. Happily, node is up to date, but npm is still several released behind (2.11.3).
The most disturbing part of all of this: npm uninstall -g npm and the packages still work, which makes me think I've got a rogue npm installation rumbling around somewhere in my box, but I cannot find it.
Thanks in advance for your time and consideration!
Node loads modules from several locations by default, and is also influenced by your environment. Take a look in these locations to see if you have modules installed that you weren't aware of.
$HOME/.node_modules
$HOME/.node_libraries
<prefix>/lib/node_modules (where <prefix> is e.g. /usr or /usr/local
Any path(s) in the $NODE_PATH environment variable
./node_modules if it exists in the current directory
../node_modules if it exists
... and so on up the tree, all the way to the root of the filesystem

npm path and installation issues - suggestions

I have used to install my nodejs on D:\ drive instead of C and have set environment variables to D drive node & npm folders.
Then i changed npm installation path as "prefix=D:\node\node_modules\npm
" on "npmrc" file. So i could confirm that all user based modules are pointing on D drive npm folder instead of appdata.
I tried to install express js globally and i used to check the package tree on my cli as mentioned below,
npm ll -g
while trying this command am getting npm extraneous ERR,
Please suggest me that which way i have to use npm path and installation stuffs.
Thanks in advance.
It might seem like a good idea to install packages globally, but this is one great reason not to.
Often used packages like express, and cookies should be kept local to a package. Mostly because of versioning issues. You might have one package using express2, but your new one wants to use express3. You would have trouble if it was a global install. When in doubt leave off that -g, and use a --save instead. (This adds the package to your npm dependencies list.)
On the other hand, command line tools like mocha, yeoman, and uh not much else that I know of should be installed with the -g flag.
I'm not much of a windows person, so you'll have to look a little yourself, but I would also recommend not installing Node by hand, but instead using a version manager like nvm to do that stuff. Here's an nvm port for windows: https://github.com/coreybutler/nvm-windows

NPM basics and Local Installs?

I'm not regular node user, so my apologies if this is a stupid newbie question, but I haven't been able to find any clear documentation on this, and my feeble newbie node skills don't let me dig into myself.
I'm following along with these instructions for installing the Ghost blogging system, (a system built with NodeJS).
After telling me to open a terminal window in the just downloaded package folder, yhe instructions include the following line
In the new terminal tab type npm install --production
This confuses me. My understanding of npm is it's a package manager that, like perl's CPAN
Fetches packages from The Internet
Installs them into my local node system
That's clearly not what's happening above, but I don't know what is happening when I run that command, and since I don't run with a NodeJS crowd I don't know who to ask.
I'd like to know what NPM is doing. Specific questions
When I run npm install, it looks like it's downloading a number of packages (lots of npm http GET in the console). How does NPM know what to download?
Where is it downloading these module files to? How does npm know where to download the files?
What effect does the --production flag have on NPM's behavior?
Happy to have specific answers, or a meta-answer that points out where I can learn how npm works with (what appears to be) a application installs (vs. a system install, which is how I normally think of it)
npm has a few different installation modes. From within a module (with a package.json file) npm install installs the dependencies listed in the dependencies and devDependencies fields of the package.json file. Installation means that files the modules are downloaded, placed in the node_modules folder, then npm installed themselves, (but only their dependencies) placing modules their own node_modules folders. This continues until everything needed is installed. Use npm ls to see the tree of installed packages.
Most of the time this is what you want, because running npm install from within a module is what you would do when developing on it, and you'll want to run tests etc. (which is what devDependencies is for).
Occasionally though, you'll be coding a service that consumes modules, but should not necessarily be treated like one (not intended to be require'd). Ghost is such a case. In these cases, you need npm install --production, which only installs the dependencies, leaving the devDependencies.
When I run npm install, it looks like it's downloading a number of
packages (lots of npm http GET in the console). How does NPM know what
to download?
It reads the package.json configuration file in the current directory.
Where is it downloading these module files to? How does npm know where to download the files?
It will create and populate a node_modules directory within the current directory. The file structure is designed in to npm/node and is (mostly) intentionally not configurable.
What effect does the --production flag have on NPM's behavior?
Install just the dependencies without the devDependencies from package.json, meaning "give me what I need to run this app, but I don't intend do do development on this app so I don't need dev-only stuff".
npmjs.org has some docs, FAQ, and man pages, which are pretty good although they are mostly lacking basic introductory material.

Resources