Running node CLI module locally - node.js

I am having an node module which is a CLI script. The CLI uses the process.cwd() to get the current directory from which the cli script is invoked( that is important).
This works fine when I install the CLI module globally
(https://www.npmjs.com/package/reduxboilergen)
npm i -g <module>
But when I install it locally
npm i -S <module>
Then
1) The script is not invoked
2) I added a script in package.json and then if I run npm run "script_name", it is invoked but it always takes the directory from where the npm script is invoked as the process.cwd().
So if the folder structure is
root
- src
Then even if I run it inside src directory its picking up root as cwd() as the package.json is in root.
The node_module npm-run ( https://github.com/timoxley/npm-run)
solves this problem but is there any other way that you experts can think of so that I dont have to add this dependency?

The answer would be npx as of npm 5.2.0

Related

Run Laravel Mix without a global nodejs and npm installation

I have a laravel project and I need to build styles and scripts with laravel-mix, but a testing server (Ubuntu 20.04.4) hasn't a globally installed node. Node and npm are in different folders in the system so I run commands like this:
/path/to/node /path/to/npm install
/path/to/node /path/to/npm run dev
But when I run npm run dev (this command runs laravel-mix build), I see the error:
> mazer#2.0.0 dev
> mix
/usr/bin/env: ‘node’: No such file or directory
In the package.json it looks like this:
"scripts": {
"dev": "mix"
...
}
I checked the laravel-mix package (in node_modules) and found this: #!/usr/bin/env node. The package checks the node var in this file, but there is no node var.
I don't need to change the env file, so how can I change this path or set a temporary system var? Is there any way to simulate that the variable is there?
I have one solution for this problem.
The issue regarding naming misspelling or path symlinks.
so that you need to link symlinks for nodejs with this command
ln -s /usr/bin/nodejs /usr/bin/node
or
sudo ln -s /usr/bin/nodejs /usr/bin/node
I resolved my issue with Docker, so now I run this command on git push:
docker run --rm -v /path/to/project:/var/www/html node:16.16.0-alpine npm run dev --prefix /var/www/html
Perhaps it will be useful to someone.
UPD
I found another way to resolve it, I use PATH incorrectly and for this reason it didn't work:
Wrong
I set paths to node and npm and then add it to PATH like this:
NODE_PATH="/path/to/node_folder/node"
NPM_PATH="/path/to/node_folder/npm"
PATH="${NODE_PATH}:${NPM_PATH}:$PATH"
And the system can't find npm and node anyway.
The right way
Add /path/to/node_folders (node and npm are in it) to PATH:
NODE_DIR="/path/to/node_folder"
PATH="${NODE_DIR}:$PATH"
And then, I can run just npm install and npm run dev without full paths to them.

How does NPM resolve & run scripts from package-json?

For curiosity's sake, I want to create a folder in node_modules and be able to run it as a script in package.json's "scripts", but I have not been able to find out how to.
I've noticed with other package.json scripts like "react-scripts" that they wont work in the command line, but will when NPM runs them. How does npm resolve scripts?
Does it have to be a legit package for NPM to run it? (Like, will it check against the NPM registry for if that package exists, or contains scripts?)
If a module has a ["bin" entry in its package.json]1, then npm will put the executable script specified by that "bin" entry into a .bin folder in node_modules.
When running a script with npm run, npm will put that node_modules/.bin directory first in the PATH so they are found with npm run but not when run directly from the shell.

Npm bin script and local file reading

I've got an npm package that has the bin section for running a cli interface utility. One of the dependent scripts of this utility reads a specific file from this package directory via fs module.
The definition of the cli util is:
"bin": { "my_cli_command": "lib/cli.js" }
When I use npm link and the cli command locally everything works file.
Like:
npm link
my_cli_command
But after installing the package in another node application run the cli command causes a problem with the script file reading because node rebuilds the bin script path:
npm i --save my_lib
npx my_cli_command
There will be an error because my_cli_command reads a local package file which is not available now.
Is there a way to allow the npm bin script to read a file from it's own package?
The problem resolved.
Just started using the path.resolve method and the __dirname variable to compute a file path:
let filePath = path.resolve(__dirname, "../files/somefile.txt");
So that approach will exclude dependency on cwd and an npm cli app will be able to work with it's package files without any problem locally or installed in another project.

NodeJS - npm install practice

Created new folder and did npm install serve in it.
It created package-lock.json and node_modules/ folder.
When I run in the same folder serve it shows error:
command not found: serve
What is the way to install?
I am using: npm#6.5.0
My dev environment is MACOS
I read a great many pages on this topic and nothing worked until I tried the following
./node_modules/.bin/serve -s build
Also if you are using VS CODE you may want to bring up the terminal window outside of VS CODE - this seems to have snared a lot of people.
First of all, you should start your project running
npm init
This will create the package.json file.
Then, you can install the serve package globally.
npm install -g serve
And now you can run serve.
The serve binary was not found because the operating system cannot locate it in the PATH environment variable.
When you do the npm install serve command. The serve module is only installed into the node_modules directory found under the the project folder. Unless you explicitly include the absolute path of this node_module directory as part of your PATH env var, the OS won't know where to find serve.
Like others say, the typical practise would be to install the module using the -g flag. G means global.
When -g is used, npm will put the binary in its node directory somewhere and this this directory would have been included as part of your PATH when you install node, thus making the any new binary discoverable.
If the node.js module has a "command" and you want to run it without installing the module globally(npm install -g serve). You can run it like ./node-modules/.bin/command from the root folder of the project.
Now, what is generally used is npx, so that you can from within a project easily run any of the binaries within its local node_modules or your system's global node_modules/ and any other commands on the $PATH.
For example, here we install webpack as a local dependency. You can image doing this in a folder after running npm init. Then we run webpack without having to worry about referencing the bin file:
$ npm i -D webpack
$ npx webpack

BrowserSync: command not found after installing locally

I ran the following command for my node app:
$ npm install browser-sync --save-dev
Installation was successful, browser-sync appears in my package.json file as well as my node_modules directory.
However, when I run $ browser-sync --version to check that it's working, I get the following error:
bash: browser-sync: command not found
Why isn't this working?
Note: this question is similar, but I don't want to have to install it globally as in this question.
Any help would be greatly appreciated!
This is because you're trying to use a module locally which is normally installed globally. Modules installed globally end up on your PATH environment variable, which is why you can run them from the terminal as you're trying to do:
$ browser-sync --version
If you want to use the browser-sync module from a local install you will have to prepend the full path to the browser-sync binary from within your .bin directory since all locally installed modules are placed within your current working directory node_modules directory. i.e. Node modules go in ./node_modules, executables go in ./node_modules/.bin/. So in order to run the browser-sync binary from a local install do the following:
./node_modules/.bin/browser-sync --version
Hopefully that helps!
If you installed browser-sync using npm --save or npm --save-dev you can run it by writing a script in your package.json. Here's an example of a script I added:
{
...
"scripts": {
"dev-server": "browser-sync start --server 'public' --files 'public'"
},
...
}
You can run the scripts from you project's root directory like so
npm run dev-server
This will run whatever command is set to dev-server in your script. In this case it will run browser-sync for the app/site in a folder called /public and watch for any file changes in the /public folder. I know this question is a bit old but it was unanswered and hopefully I can save someone time in the future.
The other answers still work, but a newer approach has emerged since npm added the npx command: npx <package-name>.
This command allows you to run an arbitrary command from an npm
package (either one installed locally, or fetched remotely), in a
similar context as running it via npm run.
Source: https://docs.npmjs.com/cli/v8/commands/npx
In this case, you would run npx browser-sync.

Resources