How to force npm not to create symbolic link to local package? - node.js

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

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.

NodeJS - installing local module

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.

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.

How to install npm package while offline?

I'm working on an offline network and want to install angular-cli using npm.
I have a zip file of angular-cli and using the latest node and npm version.
I'm using the command: npm install ./angular-cli-master to install angular-cli from the folder.
But I keep getting this error telling me I don't have an internet connection (which is ok).
So how can I install this angular-cli while offline using the zip I downloaded from Github?
Thanks for your help.
You simply copy the package and all dependencies in your node_modules folder, inside the project for local installation, or in the global folder (npm config get prefix to see where it is located) for a global installation.
The behavior of npm install is to check for the dependencies, and install them first. When it doesn't find them installed, nor the local file containing them, it tries to download them.
Since all of those steps fail (you don't have the dependency installed, it isn't available on the expected location, and it can't download it), the installation fails.
You can find the dependency list in the package.json of each module, but since it is recursive, it can take a long time to have everything set right if you do it manually, npm does it by recursion.
For you, the easiest way would be to create a new folder on the connected PC, and inside it npm install angular-cli, zip the folder and transfer it on the offline machine.
Jan 2016 - check out Addy Osmani's recommendations for offline installation of npm packages
May 2017 - as of npm 5, you can pass the --prefer-offline flag to npm install
yarn does this out of the box.
In 2019, I found none recommended approaches were applicable to an "air gapped" server with no internet access.
I found the only solution was to, on windows, using artillery.io as an example:
install the package on a machine with internet access, e.g local dev machine. npm install -g artillery
Browse to C:\Users\{username}\npm
zip up the \node_modules\artillery (e.g artillery.7z)
Copy the zip and the files artillery, artillery.cmd (at root of npm folder) to the server
Paste the two artillery, artillery.cmd to the root of the servers npm folder (C:\Users\{serverusername}\npm)
Extract the zip to C:\Users\{serverusername}\npm\node_modules
This is the complicated version for just one tool. If your local machine's npm folder is relatively light on tools, you could always just zip the whole npm folder and copy + extract it on the server.
I still think it's odd that npm insists on trying to connect to the registry even when using npm pack and npm install -g <tarfile>
Problem: I'd been in similar situation where I can't install the express.js and all other dependencies specifies by package.json on my local machine (offline) using npm due to unavailability of internet connectivity.
Solution: I've a solution that works on Windows(not so sure of other platforms) through which I installed express framework with all the dependencies I required for my project which include cookie-parser, jade, morgan etc.
Steps :
Install all the package(s) on a remote machine which has an internet access.
In my case I'm using Windows on both remote as well as local machines and my requirement was of installation of express.js on local machine . So I run below command on my remote machine to install express.js
C:\Users>npm install -g express-generator`
After installation of express.js I created an app on my remote machine using:
C:\Users\Name\Desktop>express Project`
C:\Users\Name\Desktop\Project>npm install -g =>to install all other dependencies globally*
Now browse to location where npm's global modules are stored, you can view the location by
C:\Users>npm config get prefix
Generally in Windows its
C:\Users\{Username}\AppData\Roaming\
Simply copy the npm and npm-cache folder of your remote machine.
And place both copied folders viz. npm and npm-cache into your local machine on same location thats
C:\Users\{Username}\AppData\Roaming\
the short answer, you can't. Most NPM packages such as #angular/cli need other dependencies and those need child dependencies which get installed when you run npm install
You can, however, install the cli when on the network and use it when offline.
You can find the npm install command documentation here: https://docs.npmjs.com/cli/install
I am not quite sure and unfortunately, I do not have the chance to test it myself right now, but I would try to either unzip the folder and remove the dot, like that:
npm install /angular-cli-master
(= installing a folder not a zip file)
or just add the zip file ending like that:
npm install ./angular-cli-master.tgz
(= installing a zip-file not a folder, file ending may be .zip or something else, though)
Was test success with node 18.x.x.
The following step guild how to install http-server package
On Online PC:
npm install -g http-server
After finish install, copy http server folder. (Usually locate at: C:\Users[UserName]\AppData\Roaming\npm\node_modules)
On offline PC:
Paste http-server folder. e.g. D:\http-server
npm install -g D:\http-server
Online computer:
npm install -g offline-npm
copy the npm-module to the offline computer and thats it !

npm install from local packages only

I'm familiar with Python's package manager pip. Pip has an option to specify "never make any network calls, all packages and dependencies should be fetched from a local directory".
Is something similar possible with npm?
I want a lighter weight build process, and want all the node packages to be installed from a local folder with .tgz files or similar.
If the folder in question will be used as a package repository of sorts, I think npm link should do the job
cd ~/<local-packages-dir>/<pkg>
npm link
cd ~/<project-dir>
npm link <pkg> // installs package to ~/<project-dir>/node_modules/<pkg>
Any changes to made to ~/<local-packages-dir>/<pkg> after being linked will be reflected in ~/<project-dir>/node_modules/<pkg>.
Also to note, npm install will install a tarball or a folder directly
npm install <folder>:
Install a package that is sitting in a folder on the filesystem.
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.
Example:
npm install ./package.tgz

Resources