How is this npm switch fixing Windows path length issues - node.js

On Windows NPM has issues due to its deep nesting of dependencies. In order to fix this a friend suggested the following command
npm install <dep> -g --no-bin-link
The man pages say about this command
The --no-bin-links argument will prevent npm from creating symlinks for any binaries the package might contain."
Could anyone explain, in plain language, what the impact this flag has on allowing dependencies to be installed that would usually causing deep path issues?

Could anyone explain, in plain language, what the impact this flag has on allowing dependencies to be installed that would usually causing deep path issues?
Sure. Many packages published on npm can be used both as a command-line tool and programmatically. For example the jslint package publishes both a command-line tool for linting files and an API that can be required, so you can write code that uses jslint
The deep path issues usually become visible when creating the files that go into the bin directory, for command-line use. The deep paths usually do not affect packages used programmatically with require.
So for "regular" dependencies of a package, it is usually harmless to omit the bin links, because those dependencies are consumed with require.
For "dev" dependencies or packages installed globally, it is usually necessary to keep the bin links, because those packages are more likely to be used as command-line tools.
Incidentally you should update to the latest npm if you haven't yet -- latest is 2.1.16 at this writing, and a guide for updating npm on windows is here: https://github.com/npm/npm/wiki/Troubleshooting#upgrading-on-windows

Related

Can you prevent node.js from installing packages locally? (Use global packages)

I've been working on a lot of different node.js projects. All of them have their own package.json file with their own needed packages. Every time I run node <mainfile>.js, npm installs all the packages to the project directory. Like so: C:/Users/me/Projects/<project-name>/node_modules.
This isn't a very big problem, but is there a way to make npm use/install to the global packages? Like in C:/Users/me/node_modules?
One of the advantages I could see this having is less storage being taken up, although it isn't a huge advantage.
I would assume that if it is possible, it would require you to add/modify something in the package.json file.
While looking into answers for this question, I've seen people saying that you should avoid installing packages globally. Can you also explain why this is a bad practice andy why I should avoid it?
Install Package Globally
NPM installs global packages into //local/lib/node_modules folder.
Apply -g in the install command to install package globally.
npm install -g express
To answer your other question
The obvious short answer is that your project depends on them. If your
project depends on a package, it should be documented in package.json
so that you can guarantee that it is installed when someone types npm
install. Otherwise, you’ll need to add extra steps in your README file
to inform anyone else who clones your project that they need to
install each of your global dependencies as well
Finally, even if someone installs the correct version of Browserify
for your project, they may be working on a different project that
requires a different version of that same tool, which would cause
conflicts. Several of your own projects might even use different
versions of Browserify because you updated it when you started a new
project and didn’t go back to make sure that earlier projects were
updated to work with the new version. These conflicts can be avoided.
You can only have one version installed globally. This causes problems if you have different projects that rely on different versions of a package.
Why not to install all packages globally
It's not really you shouldn't install a package globally it's more knowing what packages to install globally. The packages to install globally are ones that your project/application does not depend on.
How to identify a package that my project depends on
A package that your project is depended on is a package that your application could not run without like axios or express (an express API could not run without express installed or a web page that makes API requests with axios cant make those requests without axios) but something like http-server or minify is not needed to run the application so it can be installed globally.
Why is it important to have locally installed packages
It's important/good practice because if you are working with a group of developers or someone gets your work from Github they can just run npm install and get all the packages with out having to find all the packages them selfs.
How can I remove the node modules folder
You could technically globally install every package but I would sudjest not to. Node and many other developers know this is an issue that they have created a solution for in deno "the node killer".
I would recommend not installing all packages globally and if the node modules folder really annoys you try deno it fixes a lot of things that node developers hate.

npm install is really slow every time

when running npm install --no-optional, it takes around 3 mins every time to complete. It installs ~ 200MB of files. I would like to speed the build process, but I cannot find any ways to really speed it up.
Doesn't npm install by default cache dependencies (like any other decent tool e.g. maven, sbt or nuget) by default? If yes, shouldn't it be much faster than that? If no, then WHY and how to work around that?
I found npm-cache package, but it seems to .tar all the dependencies and when neither of them changes, npm-cache will reuse the tar file. The downside of this is that, whenever a small change in dependencies occurs, it won't be able to reuse the cache (from what I understand).
Are there any nice resources on why this is slow and how to speed it up and how caching works with npm in general? Other tools that I have used (sbt, maven, nuget) are much faster, therefore my expectations are high for npm as well.
Another option I looked into is npm install -g, but it seems not to solve any problems here, as it is meant to be used for installing some cli tools like grunt, npm-cache and etc., as it adds them to a path. So this definitely doesn't solve the problem.
npm -v: 4.0.5
node -v: 6.8.1
The problem with node was that coming from sbt background, where sbt uses a local ivy cache to cache dependencies, I expect the same behaviour from Node. So at least up to V 5.0, Node didn't have a proper dependency caching mechanism, so you basically needed to redownload all of the dependencies every time you do a node install with a clean node_modules folder.
There were some tool developed to work around that, but none of them were satisfactory.
But it seems that this might have been fixed in Node V 5.0 with some caching strategy, therefore if you have a similar issue, please take a look at the changes for the 5th version.
It's better to install pnpm package using the following command:
npm i -g pnpm
pnpm uses hard links and symlinks to save one version of a module only ever once on a disk. When using npm or Yarn for example, if you have 100 projects using the same version of lodash, you will have 100 copies of lodash on disk. With pnpm, lodash will be saved in a single place on the disk and a hard link will put it into the node_modules where it should be installed.
As an example I can mention that whenever you want to install the dependencies of package.json file, what you should do is simply that enter the pnpm i and it handles the other things by itself. Its speed is faster than the npm, because it will reuse the dependencies that you've installed them before!

NPM install bunch of packages not from package.json file

Using Visual Studio code as IDE but lately when I run the command - npm install from the app folder of the solution it installs around 374 items under "node_modules" instead of just installing the packages from the package.json file.
Can someone please provide some pointers for this behavior?
My versions:
node -v
v6.9.1
npm -v
3.10.8
Go to your node_modules folder and find one of the folders matching the libraries from your package.json file. Inside you will find another package.json which describes this library. It is most likely it will also have at least a couple of entries in dependencies section.
When you run npm install npm builds so-called 'dependency tree'. It starts with your top-level package.json and checks what dependencies needs to be installed, then (using its registry) it checks what are the dependencies of these dependencies and then their dependencies and so on...
It is prudent (but often neglected) to check what are the dependencies of the libraries you decide to use. Some of them might have licenses incompatible with yours. Some of them might need a ton of code to perform a simple thing. Many will use deprecated versions, which will spam your npm install log with warnings and might actually cause some conflicts with your other dependencies.

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.

Project Makefile and conditional NPM linking

We're a small team and writing a webapp in node.js,express.js and it is bundled with a parser that is implemented in python.
I would like to use my npm link'd fork of some libraries but not interrupt my team's workflow. So if my forks exist, otherwise install local node packages.
I would like to play around with deployment scripts so I was writing a Makefile for the project. Part of the makefile's job is to use npm to get the node dependencies, so I have a target
node_modules:
##(cd $dir && npm install)
Which is all fine until I started hacking on some node libraries. Now, I have a few forks of some dependent libraries that I would like to use but don't want to interfere with the rest of my team's build.
The solutions I've seen are almost there but not quite. The --link related flags and options will install globally if the global package is not there, which is not what I want. I would like it to install locally.
npm link foo then npm install - sort of works, but npm will install foo globally if the link does not exist
devDependencies - would be good except we will all be building npm
Some sort of per user Makefile that I just keep locally that runs - this seems like an option that works, but will require some extra cruft that I'd rather not have to take care of.
I only have a bit of experience with Makefiles, so maybe there is a pattern for this already. Any ideas?

Resources