npm - install dependencies for a package in a different folder? - node.js

I have the following directory structure:
/some_project
source.js
package.json
I would like to install the dependencies for some_project.
I know I could cd into some_project and then run npm install
But I was wondering if it's possible without changing the directory ?
Something like
npm install some_project/package.json

You can use the npm install <folder> variant with the --prefix option. In your scenario the folder and prefix will be the same:
npm --prefix ./some_project install ./some_project

Update: Since the --prefix option exists, I now vote for #coudy's answer to this question. Original answer below:
No, npm will always install in the current directory or, with -g, in the system wide node_modules. You can kind of accomplish this with a subshell though, which won't affect your current directory:
(cd some_project && npm install)
The parentheses makes it run in a subshell.

On windows 10 using powershell the only thing that worked for me without all the problems and edge-cases mentioned in this blog post was this
Start-Process -Wait -FilePath "npm" -ArgumentList "install" -WorkingDirectory $web_dir

Create a package.json in the root directory with the following contents:
{
"dependencies": {
"helloworldprojectname": "file:hello\\world"
}
}
Then call this to install:
npm install --prefix ./hello/world
It installs ./hello/world/node_modules using ./hello/world/package.json.
(Windows 10, Node v10.16.0, npm 7.6.1)

On Windows 10 I couldn't get --prefix to work, so I had to cd and execute it.
cd PATH_TO_FOLDER && npm install

Related

sh: 1: node: Permission denied

Tried to run this command on ubuntu 18.04
npm install -g pngquant-bin
but I got this error,
[..................] | fetchMetadata: sill resolveWithNewModule npm-conf#1.1.3 checking installable status
npm WARN deprecated gulp-util#3.0.8: gulp-util is deprecated - replace it, following the guidelines at https://medium.com/gulpjs/gulp-util-ca3b1f9f9ac5
/root/.nvm/versions/node/v10.8.0/bin/pngquant -> /root/.nvm/versions/node/v10.8.0/lib/node_modules/pngquant-bin/cli.js
> pngquant-bin#5.0.0 postinstall /root/.nvm/versions/node/v10.8.0/lib/node_modules/pngquant-bin
> node lib/install.js
sh: 1: node: Permission denied
npm ERR! file sh
npm ERR! code ELIFECYCLE
npm ERR! errno ENOENT
npm ERR! syscall spawn
npm ERR! pngquant-bin#5.0.0 postinstall: `node lib/install.js`
npm ERR! spawn ENOENT
npm ERR!
npm ERR! Failed at the pngquant-bin#5.0.0 postinstall script.
npm ERR! This is probably not a problem with npm. There is likely additional logging output above.
npm ERR! A complete log of this run can be found in:
npm ERR! /root/.npm/_logs/2018-08-12T18_08_02_197Z-debug.log
Do you do you know how to deal with this?
I tried every solution found in this articles yet not succeeded.
Got the same error sh: 1: node: Permission denied
So this worked for me
npm config set user 0
npm config set unsafe-perm true
These issues happen because of broken packages. Go to the main folder. If using Linux use command
sudo rm -rf node_modules.
After that run this command if you are using yarn
yarn install
If you are using npm run this command
npm install
Delete the node_modules and install it again
sudo rm -rf node_modules
npm install
in fact, npm can't use root account to install anything. if you use root account, npm will create a non-permission account to install. in this case, if the package need to execute writeFile or other operation which need permission, the error node: Permission denied will be raised.
so, you can choose optional arbitrary under:
npm install xxx --unsafe-perm
npm config set unsafe-perm true
create high-permission account dedicate to execute npm install
In my case it was a silly typo, I was forgotten to add node into the front of the start command in package.json. So I've changed:
"scripts": {
"start": "app/server.js"
}
... to:
"scripts": {
"start": "node app/server.js"
}
The /root/.npm/... log path in your original message shows you're already running as root, and (despite what others advise) I'd say this is most likely causing your problem.
My (limited) experience running Node as root is that most npm install runs get quite a long way, but then fail with some variation on the error you showed. The only reliable solution I've found is to not run Node or npm as root at all on Ubuntu. Just use a normal user account to download and unpack the Node installation.
At least one problem with running as root for me turned out to be because some dependency-of-a-dependency npm install script was calling setuid to switch to a less-privileged user. For some reason, it chose UID 500—which doesn't exist on Ubuntu—and consequently lost all its privileges. The 'Permission denied' errors were therefore because I was running as root; setuid doesn't work for a normal user.
I believe this is related to Error: setuid user id does not exist npm ERR! when npm install forever -g.
Solved my problem chmod -R a+x node_modules
As far as my understanding goes the os is blocking your ability to execute commands described in node_modules so by my understanding what this command does is say everything in node_modules is okay to execute.
By the time I found the solution it was 4 AM, so I didn't really bother to figure out what I actually did. If someone knows what -R a+x node_modules does exactly feel free to drop it in the commands and I will make an edit.
I make the chown to project user owner (in USERID) dir and resolv the "permission denied" problem:
sudo chown -R USERID.USERID *
Additionally (and this might be useful for docker) you can override this configuration setting globally via the environment variable npm_config_user -- for example:
ENV npm_config_user=root
I ran into the same error an nothing really helped. I found a medium article explaining how to set up an angular build management. For some reason adding
- npm link #angular/cli#13.2.5
to my build script made it. I basically added all of the recommendations above. So my build script now looks like this
- ...
- npm config set user 0
- npm config set unsafe-perm true
- npm i --force
- npm link #angular/cli#13.2.5
- ...
I hope it helps! I would be happy if someone could explain why it actually worked.
This is an old question but maybe someone still need some help.
This errors often is displayed because you have defined in the package.json just the path. For example:
{
// more definitions
"scripts": {
// other scripts
"getPax8Products": "<filepath>",
// more scripts
},
// more definitions
}
In this case, you need to:
Add the following lines in the very beggining of the script
#!/usr/bin/env node
'use strict';
Give the file execution permission
# in UNIX based
chmod +x <filepath>
You also can modify the package.json and add the node command. However, you need to be aware that NPM will run in the script's directory:
{
// more definitions
"scripts": {
// other scripts
"getPax8Products": "node <filepath>",
// more scripts
},
// more definitions
}
For Deploying with Docker:
make sure /node_modules is deleted or added to dockerignorefile
make sure /dist is deleted or added to dockerignorefile
the problem was solved for me by deleting both files
and build them in the container
For me, I had not installed my dependencies. node_modules did not exist, but I had jest installed globally apparently. Running npm ci and then running npm test solved my issue.
npm install lite-server --save-dev
packages.json:
"scripts": {
"dev": "lite-server",
},
"devDependencies": {
"lite-server": "^2.6.1"
}
npm run dev
I stuck with same issue when tried to install packages into AWS Sagemaker instance
The issue coming because NPM by default install new global packages into ~/.npm-global
When you run npm install -g by root, npm is try to install package into /root/.npm-global/..., and stuck with access denied.
Simply workaround to re-config global folder for npm.
(https://docs.npmjs.com/resolving-eacces-permissions-errors-when-installing-packages-globally)
Here is example of install obj2gltf
mkdir /npm-global
npm config set prefix '/npm-global'
export PATH=/npm-global/bin:$PATH
npm install -g obj2gltf
I had that error too and tried the above solutions without any change. My error was caused because I had Windows (11) with a WSL and NVM installed on both operating systems. I had to uninstall NVM on my Windows to resolve the conflicts.
I think if you develop in your WSL and have a resource installed on both operating systems, a dependency might point to the wrong operating system with the resource (in my case to the NVM on Windows). The WSL user didn't have sufficient permissions to perform any execution on the Windows machine, which lead to the error.
you need root user permission, just add sudo keyword before the command and write your password
sudo npm install -g pngquant-bin
Try to install node at project folder
npm install node

How to run npm install without changing working directory

How to install dependencies for project without changing working directory to project root?
Curently you need to execute:
cd /my/project/root && npm install && cd -
I'm looking for an option like -C for Makefile so that I can:
npm install -C /my/project/root
Any ideas on how to accomplish this?
A colleague of mine has found a way to do this (note that this is not documented in npm help but online):
npm install --prefix /my/project/root
Or the short version (only documented online)
npm install -C /my/project/root

How to clean node_modules folder of packages that are not in package.json?

Assume I install project packages with npm install that looks into package.json for modules to be installed. After a while I see that I don't need some specific module and remove its dependency from package.json. Then I remove some other modules from package.json because they are not needed anymore and others are replaced with alternatives.
Now I want to clean node_modules folder so that only modules listed in package.json stay there and the rest must go, something like npm clean. I know I can remove them manually but would like to have some nice ready to use sugar functionality for that.
I think you're looking for npm prune
npm prune [<name> [<name ...]]
This command removes "extraneous" packages. If a package name is
provided, then only packages matching one of the supplied names are
removed.
Extraneous packages are packages that are not listed on the
parent package's dependencies list.
See the docs: https://docs.npmjs.com/cli/prune
You could remove your node_modules/ folder and then reinstall the dependencies from package.json.
rm -rf node_modules/
npm install
This would erase all installed packages in the current folder and only install the dependencies from package.json. If the dependencies have been previously installed npm will try to use the cached version, avoiding downloading the dependency a second time.
Due to its folder nesting Windows can’t delete the folder as its name is too long. To solve this, install RimRaf:
npm install rimraf -g
rimraf node_modules
From version 6.5.0 npm supports the command clean-install (ci) to hard refresh all the packages.
Please, see the references:
npm 6.x: npm-ci | npm Docs.
npm 7.x: npm-ci | npm Docs.
npm Blog Archive: Introducing npm ci for faster, more reliable builds.
simple just run
rm -r node_modules
in fact, you can delete any folder with this.
like rm -r AnyFolderWhichIsNotDeletableFromShiftDeleteOrDelete.
just open the gitbash move to root of the folder and run this command
Hope this will help.
First globally install rimraf
npm install rimraf -g
go to the path using cmd where your node_modules folder and apply below command
rimraf node_modules
Just in-case somebody needs it, here's something I've done recently to resolve this:
npm ci - If you want to clean everything and install all packages from scratch:
-It does a clean install: if the node_modules folder exists, npm deletes it and installs a fresh one.
-It checks for consistency: if package-lock.json doesn’t exist or if it doesn’t match the contents of package.json, npm stops with an error.
https://docs.npmjs.com/cli/v6/commands/npm-ci
npm-dedupe - If you want to clean-up the current node_modules directory without deleting and re-installing all the packages
Searches the local package tree and attempts to simplify the overall structure by moving dependencies further up the tree, where they can be more effectively shared by multiple dependent packages.
https://docs.npmjs.com/cli/v6/commands/npm-dedupe
Have you tried npm prune?
it should uninstall everything not listed in your package file
https://npmjs.org/doc/cli/npm-prune.html
The best article I found about it is this one: https://trilon.io/blog/how-to-delete-all-nodemodules-recursively
All from the console and easy to execute from any folder point.
But as a summary of the article, this command to find the size for each node_module folder found in different projects.
find . -name "node_modules" -type d -prune -print | xargs du -chs
And to actually remove them:
find . -name 'node_modules' -type d -prune -print -exec rm -rf '{}' \;
The article contains also instructions for windows shell.
I have added few lines inside package.json:
"scripts": {
...
"clean": "rmdir /s /q node_modules",
"reinstall": "npm run clean && npm install",
"rebuild": "npm run clean && npm install && rmdir /s /q dist && npm run build --prod",
...
}
If you want to clean only you can use this rimraf node_modules or rm -rf node_modules.
It works fine
You can also use npx in combination with rimraf to remove all node modules with one command, so you don't have to install rimraf first.
So go to the path where your node_modules folder is located by using cmd (in case you are not there already) and run the following command
npx rimraf node_modules
For Windows User, alternative solution to remove such folder listed here: http://ask.osify.com/qa/567
Among them, a free tool: Long Path Fixer is good to try: http://corz.org/windows/software/accessories/Long-Path-Fixer-for-Windows.php
rimraf is an package for simulate linux command [rm -rf] in windows. which is useful for cross platform support. for install its CLI:
npm install rimraf -g
If you are using YARN in your project please add below line to your pacjage.json script and run yarn clean to execute on project terminal
"clean": "rm -rf yarn.lock node_modules ios/Podfile.lock && yarn install && cd ios && pod install && pod update && cd .."
Use following command instead of npm install
npm ci

How to npm install to a specified directory?

Is it possible to specify a target directory when running npm install <package>?
You can use the --prefix option:
mkdir -p ./install/here/node_modules
npm install --prefix ./install/here <package>
The package(s) will then be installed in ./install/here/node_modules. The mkdir is needed since npm might otherwise choose an already existing node_modules directory higher up in the hierarchy. (See npm documentation on folders.)
As of npm version 3.8.6, you can use
npm install --prefix ./install/here <package>
to install in the specified directory. NPM automatically creates node_modules folder even when a node_modules directory already exists in the higher up hierarchy.
You can also have a package.json in the current directory and then install it in the specified directory using --prefix option:
npm install --prefix ./install/here
As of npm 6.0.0, you can use
npm install --prefix ./install/here ./
to install the package.json in current directory to "./install/here" directory. There is one thing that I have noticed on Mac that it creates a symlink to parent folder inside the node_modules directory. But, it still works.
NOTE: NPM honours the path that you've specified through the --prefix option. It resolves as per npm documentation on folders, only when npm install is used without the --prefix option.
In the documentation it's stated:
Use the prefix option together with the global option:
The prefix config defaults to the location where node is installed. On
most systems, this is /usr/local. On windows, this is the exact
location of the node.exe binary. On Unix systems, it's one level up,
since node is typically installed at {prefix}/bin/node rather than
{prefix}/node.exe.
When the global flag is set, npm installs things into this prefix.
When it is not set, it uses the root of the current package, or the
current working directory if not in a package already.
(Emphasis by them)
So in your root directory you could install with
npm install --prefix <path/to/prefix_folder> -g
and it will install the node_modules folder into the folder
<path/to/prefix_folder>/lib/node_modules
There currently is no documented way to install a package in an arbitrary directory. You should change into the target directory, make sure it has a package.json, and then use the regular commands.
While there currently is an undocumented option called --prefix, this feature might be removed in a future release. At least, it it is not planned to ever document this as an official feature.
I am using a powershell build and couldn't get npm to run without changing the current directory.
Ended up using the start command and just specifying the working directory:
start "npm" -ArgumentList "install --warn" -wo $buildFolder

How to install npm -g on offline server

I need to install a "global" npm applications on an offline server.
It is easy to install a normal application:
npm install
and then pack up the resulting files. Either manually or using npm pack.
However, how can I install global application (that has a install script of some sort) such as forever without Internet?
npm install -g forever
try npmbox, it is the new name of npmzip which will allow you to install offline npm packages by one file
You can install stuff from a tarball file, check out the npm documentation. You can find the URL of the forever tarball with npm view forever dist.tarball and download that. Try something like this:
curl -so forever.tar.gz `npm view forever dist.tarball 2> /dev/null`
npm install ./forever.tar.gz -g
But you might have to do this for all of the dependencies as well. There might be a better way but this is what I've found in my search.
Well.... after a day trying to make it work with above references (npmbox or offline-npm) came up with something way much simpler. Thanks to npmbox I have to say.
The idea is the keep the cache from the instance that has online access and then use it in the one offline.
In machine with internet:
1 - clear npm cache: npm cache clear
2 - install package, lets say its x.y.z: npm install -g **package.x.y.z**
3 - copy cache in to a folder... let's call it whatever (I assume npm cache is in root folder, not absolutely sure about that):
cp -R /.npm/* **/cache-whatever-folder**
In machine with no internet:
4 - take this cache-whatever-folder to the instance with no internet and after that, clean cache and install with it (I won't indicate how to copy the folder :)
npm cache clear
npm install --global --cache **/cache-whatever-folder** --optional --cache-min 99999999999 --shrinkwrap false **package.x.y.z**
Done
INSTALL PM2 OFFLINE:-
Tested on Node-v6.10.3 and Npm-3.10.10 on RHEL-7
Go to machine with internet connection:-
#npm install -g npmbox
#npmbox npmbox
#scp npmbox.npmbox root#offline-server-ip:.
Go to machine without internet connection :-
#ssh root#offline-server-ip
#tar --no-same-owner --no-same-permissions -xvzf npmbox.npmbox
#npm install --global --cache ./.npmbox.cache --optional --cache-min 99999999999 --shrinkwrap false npmbox
Go to machine with internet connection:-
#npm install pm2 -g
#npmbox pm2
#scp pm2.npmbox root#offline-server-ip:.
Go to machine without internet connection :-
#npmunbox pm2.npmbox --global
#pm2 ls
I created offline-npm for getting all the dependencies installed in a clean way. For modules without the use of node-gyp everything should work as described.
If you require node-gyp (which is usually installed online) consider copying ~/.node-gyp to that offline machine.
Try npmzip
npm install -g npmzip
npmzip <package>
You will get the tarball in the current directory
This may be moved to the target machine and :
npmunzip <tarball>
Using Yarn:
On the internet machine (configure local cache location):
yarn config set yarn-offline-mirror ~/yarn-offline-mirror/
On the offline machine (configure local cache location):
yarn config set yarn-offline-mirror ~/yarn-offline-mirror/
On the offline machine, Find out where is the global installation location:
yarn global bin
(Or set it with yarn config set prefix <file_path>)
On the offline machine, add it to your path. E.g.:
echo 'export PATH=$PATH:'"$(yarn global bin)" >> ~/.bashrc
source ~/.bashrc # reload
On the internet machine, download forever's dependencies:
mkdir new-cli-forever/
cd new-cli-forever/
yarn add forever
Then copy new-cli-forever/yarn.lock and ~/yarn-offline-mirror/ to the offline machine. (rm -rf new-cli-forever/ is ok now.)
On the offline machine, install forever from local cache:
cp /path/to/imported/yarn.lock .
cp -n /path/to/imported/yarn-offline-mirror/* ~/yarn-offline-mirror/
yarn global add --offline forever
rm -f ./yarn.lock
For more info, see my post here: https://assafmo.github.io/2018/04/11/yarn-offline.html
List the dependencies in bundledDependencies in your package.json, and then run npm pack to create a tarball. Get that over to the other machine, and either npm install <tarball>, or just crack it open manually.
https://github.com/npm/npm/issues/1349
npmbox is outdated
Use npm pack command (npm docs), no need to install anything.
Single package
If you want only one package (for example, forever), you can run:
npm pack forever
this command will fetch it to the cache, and then copy the tarball to the current working directory as -.tgz
Then, from the folder you created the package, you install it with:
npm install -g ./forever-x.y.z.tgz
Whole project
If you want a whole project to be installed offline, include a poperty in your package.json named bundleDependencies and list all dependecies you need in this field.
// package.json
"dependencies": {
"archiver": "^2.1.1",
"axios": "^0.16.2",
"body-parser": "^1.18.3"
},
"bundleDependencies": {
"archiver": "^2.1.1",
"axios": "^0.16.2",
"body-parser": "^1.18.3"
}
Then run npm pack.
It will create a .tgz file of your whole project and dependencias.
You just have to copy it to the offline server and untar.
On your local machine or any machine that has internet connection, do
npm install npm-bundle -g
npm install forever -g
Now, go to cd /usr/local/lib/node_modules/forever and do
npm-bundle
It will create a .tgz file. Now scp/ftp that .tgz file to the offline server and do
npm install forever -g
Reference: This blog
On an online machine do:
# change to desired packages
packages="pm2 yarn"
for pkg in $packages; do
mkdir "$pkg"
curl "$(npm view "$pkg" dist.tarball)" |
tar -xzC "$pkg" --strip-components 1
(cd "$pkg" && npm install)
done
tar -czf packages.tar.gz $packages
On the offline server do:
npm config set offline
tar -xzf packages.tar.gz
npm install -g pm2 yarn

Resources