Why can I run globally installed node modules by name? - node.js

I install a node module globally, let's say the grunt module. I install it by:
npm install -g grunt
It's installed in %APPDATA%\npm\node_modules\grunt.
Then I can run it in command line, like grunt --version. How does this happen? I mean, why can I directly use grunt as a command?
BTW, I'm using Windows. And I install NodeJS by .msi installer.

You aren't really running the grunt package as a whole from the command.
The setup for this starts in grunt's package.json. In that, it's specified a bin script that's named the same as the package.
"bin": {
"grunt": "bin/grunt"
},
When you install the package globally, npm adds an executable file for each bin script (there can be multiple per package) to a directory in your system's PATH, allowing a command line to find them when you type the command.
When you run grunt, it's sort of a shortcut to running node bin/grunt from the directory where it's installed, passing along any arguments you provided after it.

Related

How to use node modules from command line?

I can't find any straightforward instructions on this. I've installed node.js and npm, then created a project in its own folder, D:\node_stuff, then cd'd there via cmd (Windows 10) and ran npm install express, npm init. I'm trying to use gifify, and installed its dependencies via npm instead of brew (ffmpeg, imagemagick, giflossy).
gifify -h -> 'gifify' is not recognized as an internal or external command,
operable program or batch file.
node gifify -h -> Error: Cannot find module 'D:\node_stuff\gifify'
cd node_modules -> node gifify -h -> nothing happens
What am I doing wrong? Where do I even look - all tutorials with simple search only show how to install packages or build a project - I don't need to build anything, only to use this one module.
You can run npx gifify -h.
Generally, you have two options when installing NPM packages:
install globally e.g. npm install gifify -g
install locally e.g. npm install gifify (or npm install if the package is listed in package.json)
Some packages, when installed, also install a command-line script. For globally-installed packages, that CLI script is installed to a location that is in your PATH and hence you can simply run the bare command e.g. gifify -h. For locally-installed packages, that CLI script is installed locally under the node_modules folder, which is not in your PATH. To run such a script you can use the NPM package executor npx, for example npx gifify -h. This essentially executes the local script from the node_modules/.bin folder.
If your package script, e.g. gifify, relies on third-party executables such as FFMPEG and ImageMagick, then I would install those as regular applications (which will put them on your PATH).

BrowserSync: command not found after installing locally

I ran the following command for my node app:
$ npm install browser-sync --save-dev
Installation was successful, browser-sync appears in my package.json file as well as my node_modules directory.
However, when I run $ browser-sync --version to check that it's working, I get the following error:
bash: browser-sync: command not found
Why isn't this working?
Note: this question is similar, but I don't want to have to install it globally as in this question.
Any help would be greatly appreciated!
This is because you're trying to use a module locally which is normally installed globally. Modules installed globally end up on your PATH environment variable, which is why you can run them from the terminal as you're trying to do:
$ browser-sync --version
If you want to use the browser-sync module from a local install you will have to prepend the full path to the browser-sync binary from within your .bin directory since all locally installed modules are placed within your current working directory node_modules directory. i.e. Node modules go in ./node_modules, executables go in ./node_modules/.bin/. So in order to run the browser-sync binary from a local install do the following:
./node_modules/.bin/browser-sync --version
Hopefully that helps!
If you installed browser-sync using npm --save or npm --save-dev you can run it by writing a script in your package.json. Here's an example of a script I added:
{
...
"scripts": {
"dev-server": "browser-sync start --server 'public' --files 'public'"
},
...
}
You can run the scripts from you project's root directory like so
npm run dev-server
This will run whatever command is set to dev-server in your script. In this case it will run browser-sync for the app/site in a folder called /public and watch for any file changes in the /public folder. I know this question is a bit old but it was unanswered and hopefully I can save someone time in the future.
The other answers still work, but a newer approach has emerged since npm added the npx command: npx <package-name>.
This command allows you to run an arbitrary command from an npm
package (either one installed locally, or fetched remotely), in a
similar context as running it via npm run.
Source: https://docs.npmjs.com/cli/v8/commands/npx
In this case, you would run npx browser-sync.

how to set grunt variable env path

I am trying to set grunt for my node.js project and I have followed below steps:
1)I have installed node.js and it is working fine.
2)Installed git.
3)Installed grun by running: npm install -g grunt-cli.
C:\Users\user\Downloads\bpost-gs-api-1.1.1>npm install -g grunt-cli
C:\Users\user\AppData\Roaming\npm\grunt -> C:\Users\891153\AppData\Roaming\npm\node_modules\grunt-cli\bin\grunt
C:\Users\user\AppData\Roaming\npm
`-- grunt-cli#1.2.0
Now I have run the cmd grunt -version, I got below error:
grunt is not recognized as an internal or external command,
operable program or batch file.
Can you please help me to set up grunt for my project. How to setup variable env and how to setup path etc.
Appreciate your help
https://gruntjs.com/getting-started
In order to get started, you'll want to install Grunt's command line interface (CLI) globally. You may need to use sudo (for OSX, *nix, BSD etc) or run your command shell as Administrator (for Windows) to do this.
npm install -g grunt-cli
This will put the grunt command in your system path, allowing it to be run from any directory.
Note that installing grunt-cli does not install the Grunt task runner! The job of the Grunt CLI is simple: run the version of Grunt which has been installed next to a Gruntfile. This allows multiple versions of Grunt to be installed on the same machine simultaneously.
start from reading this:
https://gruntjs.com/installing-grunt
If you need a specific version of Grunt or a Grunt plugin, run npm install grunt#VERSION --save-dev where VERSION is the version you need.
for better understood on how to start setup a grunt project: https://gruntjs.com/getting-started#preparing-a-new-grunt-project
A typical setup will involve adding two files to your project: package.json and the Gruntfile.
package.json: This file is used by npm to store metadata for projects published as npm modules. You will list grunt and the Grunt plugins your project needs as devDependencies in this file.
Gruntfile: This file is named Gruntfile.js or Gruntfile.coffee and is used to configure or define tasks and load Grunt plugins. When this documentation mentions a Gruntfile it is talking about a file, which is either a Gruntfile.js or a Gruntfile.coffee.

How to put local node package on path?

Newbie question. I have chosen not to install express with -g option. I did not use npm -g which would put it on the path globally. Instead it is installed in my local mac user directory. What I am not clear on is exactly what or how you put a package like express on the path so it can be invoked etc? What exactly needs to be on the path (node_modules?) so these packages are available just like a -g installation? I could have used home-brew I suppose but anyway, I now have all node packages and everything local. Another situation is that I am not able to run any of the nodejs tutorials. Although there might be smarter ways to do this, I wonder if sudo is really such a good way to install a development package ....
Now for example, I want to run the tutorial javascripting which is a nodejs tutorial. How do I do this. If I just type:
Mac1$ javascripting
it finds nothing.
Same for
Mac1$ express
UPDATE: THIS WAS ANSWERED IN THE COMMENTS
The commands exist in a hidden directory after a regular
install npm install express
in my case this the command goes here: /users/MAC1/node_modules/.bin
It is this path that needs to be placed on the $PATH as described in the first comment.
Thanks guys.
npm installes executable to two places. By default running a npm install in a project will install any binaries in ./node_modules/.bin. When you use the -g flag (npm install -g package-name) it will install into a global path. You can find out the global path by running npm bin -g. Add that to your path and globally installed executables will be accessible.
You can also add ./node_modules/.bin to your path to allow easy access to executables added by packages in your project folder. I admit to using this on a trusted local machine. However, this is very dangerous and not a recommended way to expose the executables in the node_modules directory.
Best alternative is to add the executable to the scripts section of the package.json file and then use npm run-script <command> which will auto prepend the ./node_modules/.bin when executing.
package.json
{
"scripts": {
"foo": "foo --arguments"
}
}
Example
$ npm install foo
$ ls ./node_modules/.bin
foo
$ npm run-script foo
# Executes:
./node_modules/.bin/foo --arguments

Bower, Grunt on Ubuntu 12.04 - command not found

I've installed bower and grunt on my machine but non of it works. I get :command not found for both.
I've placed paths to bower and grunt in .bash_profile file, like:
export PATH="/home/user/.node/lib/node_modules/grunt-cli/bin:$PATH"
export PATH="/home/user/.node/lib/node_modules/bower/bin:$PATH"
It feels like packages are installed correctly but it can't be found.
Npm and node is located in home/user/.node and home/user/.npm directories is this is the right place for it?
which bower/grunt outputs nothing
Just had to remind myself of this one, to set up environment on a new machine.
As per http://gruntjs.com/getting-started, there are two steps required for installation and use of Grunt.js task runner on a given project:
You should globally install only 'grunt-cli', the Grunt Command Line Interface. This will put the grunt command on your system path. This is achieved by running npm install -g grunt-cli, which may require root privileges depending on your setup.
You should locally install the grunt task runner proper. This is achieved by running npm install, after adding the desired version of Grunt.js to your project's package.json file. This will install the specific version of Grunt.js described in your project's package.json, under the devDependencies section. This is the file used by nodejs to describe project development and deployment dependencies, among other stuff.
I managed to fix it by adding paths to .bashrc file, like:
PATH=$PATH:/home/user/.node/lib/node_modules/grunt-cli/bin
PATH=$PATH:/home/user/.node/lib/node_modules/bower
Reference

Resources