NodeJS - installing local module - node.js

npm i /path/to/module/folder will create a dependency for your project on local module
it creates a link to that folder as the docs says
• npm install < folder >:
Install the package in the directory as a symlink in the current
project. Its dependencies will be installed before it's linked. If
sits inside the root of your project, its dependencies may be
hoisted to the toplevel node_modules as they would for other types of
dependencies.
there is a flag --no-bin-links that prevent creating links only to bin's files
What i want is : is there a way to be able to make dependency on that local module by copy it not link it, so i can make changes and won't reflect on other projects until i manually npm update my-local-module it
PS : from what i searched that was the default behavior of npm install <folder> but they changed it.

You can create a tarball from your-local-module with npm-pack and then install it offline using npm-install:
npm install <tarball file>
Install a package that is sitting on the filesystem. Note: if you just want to link a dev directory into your npm root, you can do this more easily by using npm link. The filename must use .tar, .tar.gz, or .tgz as the extension.

Related

Install npm global from a local directory with dependencies

There's a public tool (csso-cli) that can be installed with npm install -g csso-cli to be available globally. Now I need to make a modification to it and change one of its dependencies (csso) to a newer version to use the latest features. So I cloned the repository and installed that with npm install -g ./. It did copy that local code directory to my global npm installation location, but none of the required dependencies were added. There simply isn't a node_modules subdirectory in the install location.
How can I properly install an npm package from a local directory, including all external dependencies, as if it were installed from a public repository? Maybe I need to create some sort of package file first and install that? I don't know much about npm. I searched the web but couldn't find anything. (All instructions are missing the dependencies.) I've read the npm documentation but am still no wiser. That topic isn't covered here, still only incomplete installations without dependencies seem possible. Who needs that?
Looks like I needed the npm pack command. It creates an archive of the package from the local directory. When installing that file with npm install -g my-package-1.0.0.tgz all dependencies are properly installed as well. Plus, the package file doesn't contain the git files.

How to force npm not to create symbolic link to local package?

I downloaded local copy of npm package and extracted it on desktop.
Then I used npm install /directory/ to install it.
What I noticed is that when I remove desktop directory, app says it can't find installed module. After further investigation I noticed that package is in node_modules but it has arrow next to it and it says "symbolic link" which I suppose is a link to desktop directory with this package.
How do I install it independently so that it is fully contained in node_modules allowing me to remove desktop copy?
Turns out you can use
npm pack /path/to/package
This will cause npm to pack package into a .tgz file.
Then you can install it from a .tgz file using a standard
npm install /path/to/file.tgz
This will force npm to create a local copy in node_modules without symbolic link

npm link does not care for "files" in package.json or .npmignore

My goal is to specify what files will be included in my node module before publishing it and be able to test the installation locally. Using the "files" in the package.json works in that if I publish my package and install it, then I get only what was specified in "files".
This isn't the case when I use npm link. Be it "files" in package.json or an .npmignore, npm link always seems to give me every file. How can I test my modules installation locally like this?
Ex:
cd ~/projects/node-redis # go into the package directory
npm link # creates global link
cd ~/projects/node-bloggy # go into some other package directory.
npm link redis # link-install the package
If ~/projects/node-redis had "files: [lib]" in its package.json, you would expect only lib to show up in ~/projects/node-bloggy after running "npm link redis", but this is not the case.
Aside:
I love node and npm, but if you look at what is in your node modules, there's so many extraneous files like PNGs used in the readme. Modules are ridiculously huge because of this.
UPDATE:
npm install <path>
seems to respect "files" in package.json according to an answer here and others on stackoverflow. I can't speak for other systems but with npm v 6.9.0 on Fedora Linux, this doesn't work as all files are still copied.
Example:
If you need a published module to test this scenario with, I recently published num2cheque which has no dependencies. You will see that if you install it from the npm registry with
npm install num2cheque
you do not receive the test directory which I have locally because in the package.json I specify
"files": [lib]
Add a test directory to your local install then try to use npm link or npm install with a path and you will see that test directory is now included. Hope that illustrates the issue.
Workaround: npm install a GIT repo URL
You may want to install a package from a GIT repo, eg
npm install https://github.com/AndreasPizsa/parse-decimal-number.git
This is an actual npm install which respects the files entry, even if the package has not yet been published to an npm repository.
Background
npm link does not copy, it creates a link
npm link does not actually install the package by copying it into the target folder.
Instead it creates a symbolic link to the source folder, which is why you’re seeing all the files that are in the source folder ("node-redis"), not just those specified in files.
This behavior is documented in the npm link documentation:
First, npm link in a package folder will create a symlink in the
global folder {prefix}/lib/node_modules/ that links to the
package where the npm link command was executed. (see npm-config for
the value of prefix). It will also link any bins in the package to
{prefix}/bin/{name}.
Next, in some other location, npm link package-name will create a
symbolic link from globally-installed package-name to node_modules/ of
the current folder.
https://docs.npmjs.com/cli/link.html
"What’s a Symlink?" you may ask:
a symbolic link (also symlink or soft link) is a term for any file that contains a reference to another file or directory in the form of an absolute or relative path and that affects pathname resolution.
https://en.wikipedia.org/wiki/Symbolic_link
If your concern is the use of space on your hard disk, worry not - nothing is copied or duplicated, only linked (just like linking to Wikipedia doesn’t duplicate it, it actually saves space)
... and so does running npm install locally
npm install with the path to the package will also create a symbolic link to the package in question. A helpful scenario for this can be a module that’s still under development.
cd ~/projects/node-bloggy
npm install ~/projects/node-redis
This will create a symbolic link under node_modules in your node-bloggy project.

Using npm how can I download a package as a zip with all of its dependencies included in the package

What I'm trying to do is download packages with all their dependencies, in order to transfer them to another computer that does not have an internet connection and install it there.
So the scenario would be:
Download package (to zip/tarball/whatever file) without installing it.
Included in that downloaded file would be all of its dependencies (correct versions, and it's dependencies' dependencies).
Transfer file to other computer.
Run npm install to file location (optional -g important).
Package is installed with dependencies.
Happy camper.
I feel like there has to be a npm command to download and pack (create) files this way.
I've tried looking for a solution for this to no avail.
This is my first time using node so I'm affraid I'm not researching it correctly because lack of knowledge of the node/npm lingo.
I just used this gist by Jack Gill to do exactly what you describe -- bundle up a package, with all its dependencies. Basically what the script does is re-write a module's package.json file to move all its dependencies to bundleDependencies, then pack the whole thing. Upload the resulting tarball to your server, then npm install it. Works a treat.
Download the package to a machine with internet.
Make sure your app package has a package.json file at its root with all of your dependencies listed in it. You can make npm save your dependencies in package.json by doing npm install dependency-name --save. The --save flag will cause npm to write the dependency to your app's package.json file if it has one. If it doesn't have on then it will do nothing. You can also instruct npm to create a package.json file for your app if you need to by simply running npm init from in your app's directory.
Run npm install from inside the app's directory. This will create the node_modules directory and install all the dependencies listed in the app's package.json file.
Zip up the directory now that it has a node_modules directory in it with all your dependencies installed. Transfer the zip archive to another machine.
Simply unpack the archive in its final destination and you're done. The app is now where it needs to be and the dependencies are already installed.
Now just run the application with node app.js, replacing "app.js" with whatever the name of the app's main entry point file is.
You can just use the npm pack command.
So for example:
npm pack lodash
This command will download the npm package and create a file lodash-4.17.4.tgz.
Installing this can be done with:
npm install ../../my-location/lodash-4.17.4.tgz
More details here:
https://docs.npmjs.com/cli/v8/commands/npm-pack
Simply run npm install in the package directory and archive the entirety of it.
Assuming there are no non-npm requirements you need to meet and both machines are running the same version of node, nothing more needs to be done. All of the downloaded dependencies will be installed inside the ./node_modules. But it is a generally good idea to archive the entire package, as the developer might have implemented some additional setup routines.
you can download package with all its dependencies with its dependents using single command. Kindly refer this link npm-package-downloader

Difference between ~/.npm, $PROJECT/node_modules, and /usr/lib/node_modules?

I installed npm and when I did my first sudo npm install some-package -g it installed that package to /usr/lib/node_modules as I expected, but then it also created several files in ~/.npm. What's the difference between these locations?
Other answers here have said that a global installation using -g should install it to your home directory by default, but for me it installs it to /usr/lib/node_modules, am I doing something wrong?
And when I do a local installation without -g it installs to the current directory $PROJECT/node_modules. What's the difference between all these locations, and what should go where?
The system wide package install directory, typically under /usr/lib is usually used for globally installed packages that provide a binary which should be available in your PATH (to be able to execute it from anywhere).
The local install directory node_modules, created by npm install at the location where you're executing npm, is typically located in your project directory and usually used for project specific dependencies.
The ~/.npm contains packages already downloaded. When installing the same package in another location, npm will lookup that package in that cache directory first.
Reference: https://docs.npmjs.com/files/folders
Related files:
.npmrc - NPM configurations at different locations
package.json - Packages and their versions for a project
Hypothetical scenario: two projects using Grunt (a Javascript based buildscripting tool):
Both projects use different Grunt versions. One project is older. Grunt can't be updated without having to adapt the whole build process, another project has just started.
You have to install "grunt-cli" system wide (using the -g flag) since it provides the grunt binary. This CLI binary will lookup for a local "grunt" in your current project directory. The "grunt" npm on the other hand, installed locally (without -g) will then be bootstrapped by the CLI. When downloading grunt for the first project npm will store downloaded packages in ~/.npm, when installing grunt for the second project, npm will lookup packages common to both projects in ~/.npm first.
There are other reasons to install packages globally, the most time they provide a binary that should be located in your PATH.
Alternatively, some packages that typically need to be installed globally can also be installed locally. You'll then have to add the path to that binary (e.g. path/to/your/node_modules/.bin/<BINARY>) to your PATH variable or just specify the full execution path.

Resources