Can't run a linux shell function from NPM script - linux

I Just defined a function in my .bashrc (and then in my .bash_profile) file. Now I'm trying to run this function, that works fine in terminal, from my package.json with npm
So I get this in my .bashrc file:
function emu(){
~/android/Sdk/emulator/emulator -use-system-libs -avd "$1"
}
and I defined this script in my package.json
"scripts": {
...
"emulator": "emu ReactNative",
...
},
And I get this error in console:
> emu ReactNative
sh: 1: emu: not found
Anyone knows how to fix it?

Related

Set variable in npm script to env var from file

I'd like to set a variable FOO (that is not in my .env file) in an npm script command to the value of the environment variable BAR (which is in the .env file).
For example, my .env file:
BAR=1234
And my package.json npm script:
{
"scripts": {
"try": env-cmd FOO=$BAR src/myScript.js
}
}
...where I'd expect FOO to equal 1234. But running npm run try throws the error:
spawn FOO= ENOENT
error Command failed with signal "SIGINT".
Footnote: I'm open to libraries other than env-cmd.
You either need to use dotenv for in your code or use cross-env in the NPM script command.
I doesn't make much sense to set an environment variable from an environment variable in the script command itself as you are assuming it is already set. Running the npm script will not pick up anything from a .env file.

How to run node.js cli with experimental-specifier-resolution=node?

Our team has built a small CLI used for maintenance. The package.json specifies a path for with the bin property, and everything works great; "bin": { "eddy": "./dist/src/cli/entry.js"}
Autocompletion is achived by using yargs#17.0.1. However we recently converted the project to use es6 modules, because of a migration to Sveltekit, i.e. the package.json now contains type: module. Because of this, the CLI now only works if we run with:
what works
node --experimental-specifier-resolution=node ./dist/src/cli/entry.js help
However, if we run this without the flag, we get an error "module not found":
Error [ERR_MODULE_NOT_FOUND]: Cannot find module...
So the question is
Can we somehow "always" add the experimental-specifier-resolution=node to the CLI - so we can continue to use the shorthand eddy, and utilize auto completion?
There are two probable solutions here.
Solution 1
Your entry.js file should start with a shebang like #!/usr/bin/env node. You cannot specify the flag directly here, however, if you could provide the absolute path to node directly in the shebang, you can specify the flag.
Assuming you have node installed in /usr/bin/node, you can write the shebang in entry.js like:
#!/usr/bin/node --experimental-specifier-resolution=node
(Use which node to find the absolute path)
However, this is not a very portable solution. You cannot always assume everyone has node installed in the same path. Also some may use nvm to manage versions and can have multiple version in different path. This is the reason why we use /usr/bin/env to find the required node installation in the first place. This leads to the second solution.
Solution 2
You can create a shell script that would intern call the cli entry point with the required flags. This shell script can be specified in the package.json bin section.
The shell script (entry.sh) should look like:
#!/usr/bin/env bash
/usr/bin/env node --experimental-specifier-resolution=node ./entry.js "$#"
Then, in your package.json, replace bin with:
"bin": { "eddy": "./dist/src/cli/entry.sh"}
So when you run eddy, it will run the entry.js using node with the required flag. The "$#" in the command will be replaced by any arguments that you pass to eddy.
So eddy help will translate to /usr/bin/env node --experimental-specifier-resolution=node ./entry.js help
Just add a script to your package.json:Assuming index.js is your entry point and package.json is in the same directory
{
"scripts": {
"start": "node --experimental-specifier-resolution=node index.js"
}
}
Then you can just run on your console:
npm start

What does running node with a module name do?

I'm new to node.js so I'm pretty sure that I am doing something wrong however I would like to understand what is going on.
I tried to run this:
$ node tslint
$
Which output nothing. It didn't fail either.
Checking the help:
$ node --help
Usage: node [options] [ -e script | script.js | - ] [arguments]
node inspect script.js [arguments]
I suspect that I should have passed in the path to the js file instead.
$ node node_modules/tslint/bin/tslint
No files specified. Use --project to lint a project folder.
Sure enough that printed an error since I didn't pass a file name which was expected.
This also works:
$ npx tslint
No files specified. Use --project to lint a project folder.
So my question is, what does node tslint do and why does it neither to find the script nor actually run the script?

Can I run a command from package.json bin script?

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.

Running script in package.json works but includes errors

I just installed ESLint and I can successfully run it by doing this at the terminal window:
./node_modules/.bin/eslint app
Note: app is the root folder I want lint to inspect.
I then put that exact command in my package.json:
"scripts": {
"lint": "./node_modules/.bin/eslint app"
}
I expected to be able to run it in the terminal window like this:
npm run lint
Note: I know how to fix the no-undef error. My question is about the many errors lines after that.
It actually works, but it also produces a bunch of errors after showing me the correct output:
Why is that happening?
This is the default way of how the npm script runner handles script errors (i.e. non-zero exit codes). This will always happen, even if you only run a script like exit 1.
I'm not sure why this feature exists, it seems annoying and useless in most cases.
If you don't want to see this, you can add || true at the end of your script.
Example:
lint: "eslint app || true"
As you might've noticed, I've omitted the part to the eslint binary. The npm script runner already includes local binaries as part of the path when trying to run the script so there is no need to use the full path.
document is a global, so eslint thinks you are missing an import somewhere. For those cases, you can adapt your config so that the error is not reported, Something like this:
module.exports = {
"globals": {
"document": true
}
}
this should be saved as .eslintrc.js and be at the same level where your package.json is

Resources