I am trying to create a simple node js plugin. Here is what I have done till now.
package.json
{
"name": "testcli",
"version": "0.0.1",
"description": "Test CLI Tool",
"main": "index.js",
"author": "BJ",
"license": "ISC",
"bin": {
"testx": "index.js"
}
}
Beside the package.json I have a file index.js that has a single line console.log('Hi!')
now when I install the package with npm install -g (from the same directory) and then run the command testx it gives me the following error
.../AppData/Roaming/npm/testx: line 1: /node_modules/testcli/index.js: No such file or directory
How can I solve this?
You need to add a shebang to tell the shell how to invoke this script.
Try adding #! /usr/bin/env node at the beginning of your script.
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. On install, npm will symlink that file into prefix/bin for global installs, or ./node_modules/.bin/ for local installs.
For example, myapp could have this:
{ "bin" : { "myapp" : "./cli.js" } }
So, when you install myapp, it'll create a symlink from the cli.js script to /usr/local/bin/myapp.
If you have a single executable, and its name should be the name of the package, then you can just supply it as a string. For example:
{ "name": "my-program"
, "version": "1.2.5"
, "bin": "./path/to/program" }
would be the same as this:
{ "name": "my-program"
, "version": "1.2.5"
, "bin" : { "my-program" : "./path/to/program" } }
Please make sure that your file(s) referenced in bin starts with #!/usr/bin/env node, otherwise the scripts are started without the node executable!
Related
I am following the tutorial for building a cli tool in Node here -- How to Build a Command Line (CLI) Tool in Node.
Environment:
Cmder
Node 9.5.0
npm 6.11.3
Windows 10
I am to the point where it has you create it as a shell cmd and the link it using npm link. Instead of running it in my shell--the same way create-react-app does--it instead errors with a Windows Script Host error:
Line: 1
Char: 1
Error: Invalid Character
Code: 800A03F6
Source: Microsoft JScript compilation error`
When I run where npm, I get:
C:\Program Files\nodejs\npm
C:\Program Files\nodejs\npm.cmd
C:\Users\smkar\AppData\Roaming\npm\npm
C:\Users\smkar\AppData\Roaming\npm\npm.cmd`
But when I run where caph, I get:
D:\Code\projects\cap-hooks\caph.js
C:\Users\smkar\AppData\Roaming\npm\caph
C:\Users\smkar\AppData\Roaming\npm\caph.cmd`
I'm pretty sure the error is because it's trying to open it from the local javascript file on the D drive, but I don't know how to fix it. I'm trying to make a CLI tool for fun/learning, and I want to be able to install the tool globally, but I haven't been able to proceed from here/fix this.
For reference here's the file and the package.json:
package.json
{
"name": "caph",
"version": "0.0.1",
"description": "An automated cli package for generating administrative
tools and components for React projects, written in
React Hooks.",
"main": "caph.js",
"bin": {
"caph": "./caph.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "smkarber",
"license": "ISC"
}
caph.js
#!/user/bin/env node
console.log("Hello World!");
After running npm link, I can use caph in my shell, but it immediately gives me a Windows Script Host error instead of running it in the shell. I have tried numerous Github issues returned from Google as well as a handful of Stackoverflow questions, but nothing seems to directly refer to fixing this situation, and I am unable to rectify the situation.
It must be /usr/ not /user/. So caph.js should look like:
#!/usr/bin/env node
console.log("Hello World!");
Say I have a private npm package, #myprivate/repo which has the following contents in its package.json:
"scripts": {
"example": "db-migrate"
},
"bin": {
"foo": "bin/foo"
}
Where bin/foo is:
#!/bin/bash
npm run example
I now pull this into a parent repo with npm install:
package.json:
{
"dependencies": {
"#myprivate/repo": "*"
},
"scripts": {
"example": "unrelated command",
"useful": "foo"
}
}
Then running npm run useful results in the foo bin script getting called, which then attemps to call unrelated command. How do I scope the invocation to the dependency? How can I force a bin script to package its own npm dependency and rely on that? Is nested scripts in nested dependency package.json the best way, or is there a better more canonical solution?
I ended up being able to get the behaviour I want by changing the last line of bin/foo to:
npm explore #myprivate/repo npm run example
This does feel a little bit happy (I'm referencing the repo using npm explore from within itself), but it does get the job done. Would love to hear of a better solution
Is it possible to run a command from a bin script in a package.json ? I know it expects a path to file and trying to run a command there results in an error upon installation (after publishing to npm). Is it possible to run a command like it is in an npm start ?
Examples:
{
"name": "myscript",
"version": "1.0.3",
"bin": {
"myscript": "app/main.js"
}
}
This will create a symlink from the app/main.js script to /usr/local/bin/myscript
Instead, this is what I want to achieve:
{
"name": "myscript",
"version": "1.0.3",
"bin": {
"myscript": "echo hello world"
}
}
Possible workarounds are also appreciated.
This answer is updated since the old answer was a bit dated and ultimately incorrect. You can now do:
npx myscript
Have you tried running npm link https://docs.npmjs.com/cli/link which would create a link to your binary, then you can just run your script on the command line as myscript.
Say that I have a folder with a node module installed inside. How can I, using powershell, run this module ? For example, I have a folder with webpack installed inside and I'd like to be able to do something like
node webpack
This does not work because it can't find the module. However, it works if I do:
node ".\node_module\webpack\bin\webpack.js"
However, I can't really use this because I'm working on a powershell script that allows the user to define a json file with actions. For example:
{
"type": "run-node",
"options": {
"module": "webpack",
"parameters": "--configFile=config/webpack.prod.js"
}
}
As the module to execute is dynamic, I don't know where it will be (except if all module are installed in ".\node_modules\module\bin\module.js" ?), so I can't launch it.
You can define a webpack script in your package.json:
"scripts": {
"webpack": "node \"./node_module/webpack/bin/webpack.js\""
}
Then you can use npm run webpack or yarn webpack to run it.
If you're trying to execute the command within the node.js script, use the __dirname variable.
__dirname (almost) always refers to the directory that contains the script.
I've created a package.json file for my private app. In it, I have my dependencies listed, as expected. Some of those dependencies have dependencies of their own. When running npm install on my app, it's not installing the dependencies of my dependencies. Is there something wrong with my package.json file which is preventing this? ("winston" is one of my dependencies which isn't properly installing)
{
"name": "my app",
"version": "0.0.1",
"dependencies" : {
"connect" : "1.8.5",
"express" : "2.5.8",
"socket.io" : "0.8.7",
"winston" : "0.5.9"
},
"engine": {
"node": ">=0.6"
}
}
Reponse to comments: NPM installs the top level deps, fine, no errors, it looks like it works. It just never downloads the deps of the deps. Will try the -d option.
Spaces are not allowed in the name option for package.json files.
The name ends up being part of a URL, an argument on the command line, and a folder name. Therefore, the name can't contain any non-URL-safe characters.
https://docs.npmjs.com/files/package.json#name
I had the same issue and with some googling, it seems that this is a problem in node.js: https://github.com/isaacs/npm/issues/1341
I noticed the winston line is ended with ,
This is not a valid JSON.