Reputation: 5376
I try to create a simple Node.js command line tool to get around this concept. I am following this tutorial. Using npm init
, I have created a project named lb-model-discovery
. This is the content of the package.json
:
{
"name": "lb-model-discovery",
"version": "1.0.0",
"description": "loopback model discovery command line tool",
"main": "index.js",
"bin" :{
"lb-discover":"./index.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "seya obey",
"license": "ISC"
}
And this is the (very simple) content of the index.js
at the root of the project:
console.log('hello world');
After that I executed this command from within the folder (as suggested by the above tutorial):
npm install -g
This correctly install my tool as a global Node command line module. Going into the global repository of node_modules/
in my system (Windows), I can see that this is the file created in the npm folder: lb-discover.cmd
. And here is its content:
@"%~dp0\node_modules\lb-model-discovery\index.js" %*
But now when I run my new tool from the command line prompt:
$ lb-discover
instead of displaying a "Hello world" message in the console, it opens Notepad instead and merely displays the content of the index.js
file.
What am I doing wrong? How can I execute my custom Node.js command line?
Upvotes: 4
Views: 3008
Reputation: 122169
I had this issue, and looking in "$(npm config get cache)\_npm\<hash>\node_modules\.bin"
showed that all of the auto-generated scripts (<pkg>
for Bash, <pkg>.cmd
for Command Prompt, and <pkg>.ps1
for PowerShell) were present and correct - executing these directly in the appropriate shell worked fine.
This was for a simple package with a single script:
{
"name": "<pkg>",
"version": "<version>",
"bin": "lib/cli.js",
"...": "..."
}
lib/cli.js
was executable and started with:
#!/usr/bin/env node
However, the Bash version was still opened in Notepad when I tried to run the package with npx <pkg>
.
The issue seems to be that packages with .
in the name don't work correctly on Windows - switching from pkg.name
to pkg-name
or a scoped @pkg/name
worked fine across all platforms (tested on macOS, Ubuntu, Windows).
This is despite the documentation suggesting that only starting an unscoped package's name with a .
should be a problem:
- The names of scoped packages can begin with a dot or an underscore. This is not permitted without a scope.
Upvotes: -3
Reputation: 23
For anyone who thinks they've put the #!/usr/bin/env node
at the start of the script, check again! Some tutorials have an incorrect additional space.
Wrong!: # !/usr/bin/env node
Correct: #!/usr/bin/env node
Upvotes: 0
Reputation: 3323
Add #!/usr/bin/env node
to the first line of lb-model-discovery/index.js
. Then install the package again.
This script will be generated
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\lb-model-discovery\index.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\lb-model-discovery\index.js" %*
)
instead of
@"%~dp0\node_modules\lb-model-discovery\index.js" %*
Source: https://blog.npmjs.org/post/118810260230/building-a-simple-command-line-tool-with-npm
Upvotes: 5
Reputation: 5376
I was able to fix this issue by modifying the content of the lb-discover.cmd
from this :
@"%~dp0\node_modules\lb-model-discovery\index.js" %*
to this:
@IF EXIST "%~dp0\node.exe" (
"%~dp0\node.exe" "%~dp0\node_modules\lb-model-discovery\index.js" %*
) ELSE (
@SETLOCAL
@SET PATHEXT=%PATHEXT:;.JS;=;%
node "%~dp0\node_modules\lb-model-discovery\index.js" %*
)
My question is why executing npm install -g
in the first place, generated the wrong script?
Upvotes: 0