Cannot run cucumber from CLI - node.js

I managed to run cucumber from CLI with
node ./node_modules/cucumber/bin/cucumber
but I wasn't able to run it simply with
cucumber
Windows tried to run it as executable, so it opened some window about missing file association. Is there a way to solve this? Note that I don't want to add nodejs as .js file association, since I am pretty sure the same code won't work on github when travis tries to run the script.
I installed the package with npm.
"devDependencies": {
...
"cucumber": "^0.8.1",

You have to install cucumber globally, i.e. npm install cucumber -g This way, npm creates a binary / symlink in some standard 'on-path' directory (i.e., where the executables should be put), so you can run it from command line.
In my notebook (Linux), I run
sudo npm install cucumber -g
which creates a symlink
/usr/bin/cucumberjs -> /usr/lib/node_modules/cucumber/bin/cucumber.js
which means I can run it by cucumberjs command. If some dependency has cucumber command hardwired into it (without the js suffix), I'd create another symlink manually.
/usr/bin/cucumber -> /usr/bin/cucumberjs
If you run into the following problems, maybe try using nvm, not to polute your system folders.

Add this to your ~/.bashrc or ~/.bash_profile.
It will add ./node_modules/.bin to your PATH
export PATH=$HOME/bin:./node_modules/.bin:$PATH

Related

Why can I run globally installed node modules by name?

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.

How to make bin script available for npm package installed locally

I read on the npm documentation that you can't use bin scripts of locally installed packages.
So, how gulp can be launched as bin command when installed locally?
What's making it available when locally installed, I reviewed the gulp package.json and the bin scripts, I don't found any answer.
From NPMJS documentation:
To use this, supply a bin field in your package.json which is a map of command name to local file name. On install, npm will symlink that file into prefix/bin for global installs, or ./node_modules/.bin/ for local installs.
So, your locally installed packages binaries will be executable like this
./bin/node_modules/.bin/the_binary
This is if you want to launch the binary directly. Or, as specified in the scripts part of the documentation:
In addition to the shell's pre-existing PATH, npm run adds node_modules/.bin to the PATH provided to scripts.
Thus, you can simply write a wrapper script like
scripts: {
"build": "the_binary"
}
and call your script like this
npm run build
Bonus
As of npm#2.0.0, you can use custom arguments when executing scripts. The special option -- is used by getopt to delimit the end of the options. npm will pass all the arguments after the -- directly to your script:
npm run test -- --grep="pattern"
You can use lpx https://www.npmjs.com/package/lpx to
run a binary found in the local node_modules/.bin folder
run a binary found in the node_modules/.bin of a workspace root from anywhere in the workspace
lpx does not download any package if the binary is not found locally (ie not like npx)
Example : lpx tsc -b -w will run tsc -b -w with the local typescript package

'istanbul' is not recognized as an internal or external command

I have just added the istanbul test coverage module to my node.js application, but when I run (from command prompt):
> instanbul cover myTests.js
as mentioned in the documentation, I get:
'istanbul' is not recognized as an internal or external command
I am under Windows 7. The npm installation returned no error. I see nothing in the documentation about extra installation steps.
What am I missing?
The problem I see with this is when you move the project to a different server. Istanbul will need to be installed again globally. This defeats the npm model of package management. Another way to achieve this is to:
npm install --save-dev istanbul
Modify package.json script entries:
scripts: {
"coverage": "node ./node_modules/.bin/istanbul ...."
}
Then call it using:
npm coverage
A shortcut for your local machine is also to set your environment path to include node executables:
export PATH=$PATH:./node_modules/.bin
In which case, any executables installed to your package will be available on the command line automatically because of path checking.
For a module to be runnable from anywhere, you need to install it globally (with -g option).

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

Installing "global" npm dependencies via package.json [duplicate]

This question already has answers here:
Install dependencies globally and locally using package.json
(7 answers)
Closed 8 years ago.
I have a few "global" dependencies (jshint, csslint, buster, etc..) that I'd like to have automatically installed and executable via the command line when my package is installed via npm install. Is this possible?
Currently, I'm doing the following manually:
npm install -g <package_name>
from within my project: npm link <package_name>
Update:
Just came across this feature request for npm. It seems like the scripts config within package.json is the way to go?
Update Again:
Or, after reading the npm docs, maybe I'm supposed to use a .gyp file? I'm confused.
It's not possible to specify dependencies as "global" from a package.json. And, this is by design as Isaac states in that feature request you referenced:
Yeah, we're never going to do this.
But, "binaries" can still be used when a package is installed locally. They'll be in .../node_modules/.bin/. And, you should be able to queue them up with a preinstall script.
Though, if the series of commands is rather lengthy (as "jshint, csslint, buster, etc.." would suggest), you may want to look into using a build tool such as grunt to perform the various tasks:
{
// ...,
"scripts": {
"preinstall": "grunt"
}
}
I really like the pattern where you install local dependencies, then use a bash script that sets your PATH to ./node_modules/.bin.
File: env.sh
# Add your local node_modules bin to the path for this command
export PATH="./node_modules/.bin:$PATH"
# execute the rest of the command
exec "$#"
Then, you can use this script before any bash command. If you pair that with a Makefile or npm script:
File: Makefile
lint :
./env.sh csslint my_styles
File: package.json
"scripts": {
"lint": "./env.sh csslint my_styles"
}
This tasks in these files look like they reference csslint in some global location, but they actually use the version in your node_modules bin.
The really awesome benefit of this is that these dependencies can be versioned easily, just like your other node modules. If you stick with a global install solution, you could be clobbering some specific version on the user's system that is required for one of their other projects.
You should try this: https://github.com/lastboy/package-script
I've been using it to install global npm packages straight from the package.json. It works well for clients who aren't technically literate.
It even checks if the packages are already installed, if not install them!

Resources