Cant run custom CLI - node.js

I made a CLI for my project. Its in the bin folder:
#!/usr/bin/env node
// myproj/bin/cli.js
console.log('hello');
I linked the bin by using npm link. But when I run
$ cli
I get an error cli not found. What am I doing wrong?

Firstly, npm linking is a two step process as it says in the npm documentation page, so you are missing the second step. Linking is basically a way for you to introduce a dependency in another module you are working on.
Secondly, If I understand correctly what you are trying to achieve (run the module that you are developing locally as a global module), you can just use npm install -g command, from inside the project folder that you are developing.
This will install, your global module on your machine and will allow you to run it.

Related

Node JS/ Angular

I have installed Node JS and then imported an existing work project in Visual Studio Code. After that I ran npm install in the project folder, then run npm start and the app comes up fine. However, if I run an ng command I get an error telling me "ng is not valid command", even though the Angular CLI is in the modules folder.
I tried manually installing Angular CLI globally and set system path to point to the npm folder, and then the ng command works fine. What I don't understand is why do I need to install CLI globally if I just want to run that command within the project where the module is already present?
As a general rule then you will need to install globally any commands you wish to use (without NPX). This isn't really a restriction of NPM so much as it is a fundamental way in which command line programs work. The OS will only look in fixed predefined locations set in PATH. This applies to any Node based tool such as grunt or ng or whatever.
(While some systems do look for executables relative to the current working directory, or can be configured to, it's generally not a good or reliable method and NPM doesn't rely on this behaviour).
For something like the Angular CLI then installing it globally should be fine and is what many people will do. As a general rule if it is a command you want to run, rather than a dependency for a project, you can consider installing it globally. You'll notice that on the Angular CLI page the example does exactly that.
In many cases however you might want to run a command from a local project. Perhaps for a build script or something else where you want to keep it isolated. In that case you instead prefix your command with npx which will look inside the local project for commands.

CSSO npm not working while others are

I’m new to Node.js & npm and am trying to figure out why the uglifyjs module is working while the csso module is not.
i recently moved my global install to following location
/Users/myname/.node_modules_global/bin/npm
via this tutorial’s recommendation.
https://www.sitepoint.com/beginners-guide-node-package-manager/
to show they are both installed globally i do this via the command line
npm list -g --depth=0
and i get this result
/Users/myname/.node_modules_global/lib
csso#3.1.1
npm#5.3.0
uglify-js#3.0.25
for testing purposes i navigate to a local static site and run the commands using the CLI.
the uglifyjs command works. but when running the command for csso which is
$csso style.css style.min.css
i get this error
bash: csso: command not found
i’m at a loss how to even troubleshoot except this.
I think you are missing the CLI version. Please try:
npm i csso-cli
to install it.

How to install a node.js package using npm

I need help trying to install a node.js package from Github using the npm command prompt. It's an adaptive grid Jquery plugin called Masonjs: https://github.com/DrewDahlman/Mason.
It's my first time to use node.js, hence the difficulty understanding the setup instructions. I've CD'd to the project folder and run the 'install npm' and 'install bower' steps successfully, but I don't understand how to complete the remaining steps: running and building Gulp (is building necessary?).
Any help would be very much appreciated.
If you just want to use masonjs library in your project, you don't need to run gulp commands for running and building. Just cd into your project directory where you have initialized npm/bower and run npm install masonjs / bower install masonjs.
The next step would be to add the mason.js file in your index page. Now there would be different folder structure in which this mason.js file is present.
In case of npm module the path would be {your-project-directory}/node_modules/masonjs/lib
And in case of bower components the path would be {your-project-directory}/bower_components/MasonJS/dist
Now just use this library and it will work perfectly.

Locally-installed cli NPM project that is easy to execute

I'm building a cli node module. I would like people to be able to npm install it and use it right away with a command like npm my-project --arg=foo. It's meant for local project CLI use as a dev tool, not global installation.
It seems like the standard is to use bin in the package.json, but I don't understand some things about it:
When should I use bin and when should I use scripts?
How to I run the command in the including project? npm my-project doesn't do it.
Here is what I am doing now in package.json:
{
"name": "my-project",
"bin": "./cli.js"
}
And I can run it locally:
node cli.js --arg=foo
But when I npm-install my-project somewhere else, I don't know how to run the script it puts in bin (npm run my-project doesn't work), or if I'm using this correctly.
Let's start by explaining the difference between bin and scripts: the former you use if you want to provide a command line tool, the latter you use if you want to provide an additional command to npm (with some caveats though, see below).
In your situation, I think you want to use bin. However, instead of the user using npm my-project --arg=foo, they will use my-project --arg=foo, provided that your script is called my-project. To make that happen, your package.json will contain something like this:
"bin" : "./bin/my-project"
During installation, this will copy ./bin/my-project to a "bin" directory (usually /usr/local/bin on Unix-like OS'es). During development, you can call it as node bin/my-project, or even just ./bin/my-project, provided that it has correct permissions and "shebang".
EDIT: so I forgot that npm will use the package name, and not the name of the file in ./bin, as the executable name (if bin is a string). If your package is called my-project, and you install the package (you need to use the -g flag before npm will install the executable), it will create an executable called my-project, regardless of where the bin property points to.
In other words:
package.json:
"name" : "my-project"
"bin" : "./cli.js"
npm install -g:
copies ./cli.js to /usr/local/bin/my-project and sets executable permissions
END EDIT
FWIW, storing CLI tools in ./bin is convention, but not mandatory.
The scripts directive is useful for more internal purposes. For instance, you can use it to run a test suite, or linters, or pre/post install scripts.
Lastly, there are various modules available to help with command line parsing. I like docopt, but other often-used modules are commander or nomnom. You already mentioned yargs.

How can I run a script from an already installed NPM package?

Example:
npm install my-tools
npm run my-tools tool1
This doesn't work - it looks for a "package.json in my current directory. The documentation for "npm run" says:
If no package name is provided, it will search for a package.json in
the current folder
(https://docs.npmjs.com/cli/run-script)
So how can I provide a package name?
It looks like you're trying to run a script defined in the package.json of my-tools. This functionality is not supported as of npm#2.0.0.
The reference to npm run-script taking a package name is a documentation error; I have created an issue for that on the npm issue tracker: https://github.com/npm/npm/issues/7440
Some alternatives might include:
using npm explore to temporarily set current directory (etc.) into the package, e.g., npm explore my-tools -- npm run tool1
publishing tool1 etc. as bin entries in package.json instead of as scripts; this will make them accessible via the command line
depending on your needs, you may find a more heavyweight task runner such as grunt is a better approach than npm scripts and binaries

Resources