Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

npm package.json bin won't work on Windows

Tags:

I am trying to start my cli tool via the package.json bin property.

I have the following:

... "name": "mycli", "bin": "./bin/mycli", ... 

When I open the cmd in the package path and type: "mycli" it says that the command is not recognized.

Should I run an npm command? or use the scripts property? am I trying to access the bin property incorrectly?

like image 958
funerr Avatar asked Aug 15 '14 20:08

funerr


People also ask

Why npm is not working on Windows?

The Npm command not found error can appear when you install or upgrade npm. On Windows, the cause of this error could be that a PATH or system variable is not correctly set. The error can also occur if you do not have npm or Node. js installed, have an outdated version, or have permission issues.

What is bin in package json?

bin. A lot of packages have one or more executable files that they'd like to install into the PATH. npm makes this pretty easy (in fact, it uses this feature to install the "npm" executable.) To use this, supply a bin field in your package. json which is a map of command name to local file name.

How do I install npm files on Windows 10?

For Node. js projects, the easiest way to install npm packages is through the npm package installation window. To access this window, right-click the npm node in the project and select Install New npm Packages. In this window you can search for a package, specify options, and install.


2 Answers

Try to specify the name of your cli tool in the bin property, like:

"bin": {   "mycli": "./bin/mycli" // or "/bin/mycli.js" if it's a .js file } 

Then, run npm link, from inside your project folder, to create a global symbolic link to the current folder.

Don't forget to add the "preferGlobal": "true" property just before the bin property in your package.json file, in order to warn users to install your module globally.

like image 155
Rodrigo Medeiros Avatar answered Sep 22 '22 21:09

Rodrigo Medeiros


Whenever I was trying to get my app to link, I kept running into problems on Windows where the generated scripts that would execute on path would try to run the *.js file using the default Windows executable (I don't know what that would be). I'm not sure why. I think it might be because it is a JavaScript file. However, I compared the generated scripts to some of the other modules I had installed, and figured out that if I made the bin file referenced by the package.json act as though it were to be executed on a *nix machine, npm would automatically try and add the call to node.

For example:

If my package.json looks like this:

myapp/package.json

"name": "myapp", "bin": {     "myapp": "./bin/myapp" } 

My referenced bin file looks like this:

myapp/bin/myapp

#!/usr/bin/env node require("../server.js"); 

The 2 generated executable files that appear in %APPDATA%\npm show up as follows by running the command npm link from within the myapp directory (which would have package.json in the root):

myapp

#!/bin/sh basedir=`dirname "$0"`  case `uname` in     *CYGWIN*) basedir=`cygpath -w "$basedir"`;; esac  if [ -x "$basedir/node" ]; then   "$basedir/node"  "$basedir/node_modules/myapp/bin/myapp" "$@"   ret=$? else    node  "$basedir/node_modules/myapp/bin/myapp" "$@"   ret=$? fi exit $ret 

myapp.cmd

@IF EXIST "%~dp0\node.exe" (   "%~dp0\node.exe"  "%~dp0\node_modules\myapp\bin\myapp" %* ) ELSE (   node  "%~dp0\node_modules\myapp\bin\myapp" %* ) 

Bear in mind, I didn't need to make the 2 files above explicitly, I just needed to have the file to be executed as the bin file in the package.json. npm did the file creation.


Line Endings

One other thing to note that I ran into while using this method, make absolutely sure that your line endings are correct. I noticed that my bin was erroring with: ": No such file or directory" whenever I installed on *nix machines because there was an incorrect line ending. Thanks to View line-endings in a text file for example of how to print visible line endings.

For example, if you run cat -e PATH_TO_BIN and get something like this:

#!/usr/bin/env node^M$ ^M$ require("../index.js");^M$ 

You're using the wrong line endings. If you get something like this:

#!/usr/bin/env node$ $ require("../index.js");$ 

Those should be the right line endings.

like image 40
zero298 Avatar answered Sep 24 '22 21:09

zero298