How to npm install to a specified directory? - node.js

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

Related

Install global dependency manualy

I'm working on a project which is gonna be deployed on a VM(Windows OS) but I can't download dependencies because all npm ports are blocked and there is no way to open them.
So the only way to solve this is to zip all local dependencies and then copy them to the VM. This is pretty simple however I use two global dependencies: PM2 and pm2-windows-service.
My question is how to copy these two dependencies to the VM and then make them global ?
You can install global dependencies locally and use them from the node_modules path for example:
node node_modules/.bin/pm2 start app.js
instead of
pm2 start app.js
Actually I tend to recommend using the minimal amount of global dependencies ie. only npm
From npm-install:
npm install -g <tarball file>
And:
A package is:
a) a folder containing a program described by a package.json file
b) a gzipped tarball containing (a)
...
And also:
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.
Tarball requirements:
The filename must use .tar, .tar.gz, or .tgz as the extension.
The package contents should reside in a subfolder inside the tarball (usually it is called package/). npm strips one directory
layer when installing the package (an equivalent of tar x
--strip-components=1 is run).
The package must contain a package.json file with name and version properties.
Example:
npm install ./package.tgz
So just copy both (packed) packages and run the above command inside your VM, like npm i -g /pm2.tar.

NodeJS - npm install practice

Created new folder and did npm install serve in it.
It created package-lock.json and node_modules/ folder.
When I run in the same folder serve it shows error:
command not found: serve
What is the way to install?
I am using: npm#6.5.0
My dev environment is MACOS
I read a great many pages on this topic and nothing worked until I tried the following
./node_modules/.bin/serve -s build
Also if you are using VS CODE you may want to bring up the terminal window outside of VS CODE - this seems to have snared a lot of people.
First of all, you should start your project running
npm init
This will create the package.json file.
Then, you can install the serve package globally.
npm install -g serve
And now you can run serve.
The serve binary was not found because the operating system cannot locate it in the PATH environment variable.
When you do the npm install serve command. The serve module is only installed into the node_modules directory found under the the project folder. Unless you explicitly include the absolute path of this node_module directory as part of your PATH env var, the OS won't know where to find serve.
Like others say, the typical practise would be to install the module using the -g flag. G means global.
When -g is used, npm will put the binary in its node directory somewhere and this this directory would have been included as part of your PATH when you install node, thus making the any new binary discoverable.
If the node.js module has a "command" and you want to run it without installing the module globally(npm install -g serve). You can run it like ./node-modules/.bin/command from the root folder of the project.
Now, what is generally used is npx, so that you can from within a project easily run any of the binaries within its local node_modules or your system's global node_modules/ and any other commands on the $PATH.
For example, here we install webpack as a local dependency. You can image doing this in a folder after running npm init. Then we run webpack without having to worry about referencing the bin file:
$ npm i -D webpack
$ npx webpack

what's the destination does 'npm install -g xxx' install to?

For instance, npm install -g sinopia
On windows7, I will install the sinopia command and related modules inside C:\Users\xxxx\AppData\Roaming\npm.
On Redhat5, my node and npm command are in /usr/local/clo/ven/node-v4.2.3-linux-x64/bin. When I run 'npm install -g sinopia', by default, sinopia was got installed in the current directory as npm and node like below.
But currently I got a linux machine that has got sinopia installed by other person. I can not find the start script of sinopia inside node/bin, and I can find sinopia related stuff like below.
.
Where can I find the start script of sinopia? Whether the installation location of the 'npm install -g xxx' can be configured?
npm installs packages globally to its set global "root". To find what the global root is in a given environment, run npm root -g.
It will typically be inside the "prefix" directory, which you can find with npm prefix -g.
Note you can also change the prefix directory with npm config -g set prefix </new/prefix/path>.
To answer your more specific question
In order to find the sinopia executable, you can run which sinopia on linux (you might need to install which on RedHat, it should be available in your package sources). It will give you the pathname of the file that would be executed for the sinopia command.
But that could be a symlink to another location; to resolve the pathname you can use readlink -f $(which sinopia) on bash. The -f option tells readlink to follow links recursively. $(which sinopia) will be substituted by the output of the which sinopia command.
Quick edit as I see this has already been answered above.
To find the install location of packages installed globally through npm, run the following:
npm config get prefix
to update this you can use the following command:
npm config set prefix path
Source: npm global path prefix

Making "sudo npm install --save-dev gulp" in Maverics nothing's happens

I'm trying to test Gulp and I find this problem.
I installed Gulp globally with: sudo npm install -g gulp.
Then I was created the folder: mkdir my-gulp
cd my-gulp
And the I try to do this: sudo npm install --save-dev gulp
It seems work fine, no errors, but my folder my-gulp continues empty.
I can see in console, this line:
gulp#3.8.6 ../../node_modules/gulp
And I thinkig the problem is here "../../", I think it must be "gulp#3.8.6 node_modules/gulp"
What do you think? Maybe is something about $PATH?
First, you should never run npm via sudo for local packages. (In fact, you shouldn't run it as root ever, but that's a different, more complex issue to solve.)
Second, you need to initialize NPM before you can install packages. It sounds like you didn't do this.
There's two ways:
If you have an existing package.json, which contains the required information about a project, you can copy it into your folder, then edit in a text editor of your choice to get started. If the package.json includes existing dependencies, you can either remove them, or run npm i in the folder to install them.
If you are starting fresh, run npm init to set up a new package.
Once you have a valid package.json, you can install packages into your application.
As to why you are seeing ../../gulp, I'm guessing you have a package.json further up the file tree somewhere.

Possible to include a command-line in a Node module without global install?

I have a small Node module that includes a command line script in the bin directory.
"bin": {
"generate": "./bin/generate.js"
}
The generate.js script is properly executable.
This all works fine if I run npm install -g. But I'd prefer not to globally install and only have the command generate work from inside the module folder. If I run npm install from the module folder, it does correctly install all of the dependencies in a node_modules subdirectory. But then generate from the command like gives me "No such file or directory."
Thx.
I never install node modules using -g. My solution for your problem is to add this to my $PATH
# add this to ~/.bashrc, ~/.zshrc, or ~/.profile, etc
export PATH="./node_modules/.bin:$PATH"
Now, so long as your in the root of your module, you can access any binaries that have been installed as modules.
As an example, less is commonly installed with
npm install -g less
However, if you have your PATH modified as described above, you could something like this
cd my_node_module
npm install --save less
lessc less/style.less css/style.css
Without the PATH modification, you would've seen
command not found: lessc
If you don't feel like altering your PATH, you can access the binary directly
cd my_node_module
npm install --save lessc
./node_modules/.bin/lessc a.less a.css
Yay, no more npm install -g ...

Resources