Run module export as a node
or npx
script.
(See Why not ... for alternative approaches.)
So you have some code that you want to be able to run from the command line.
You can of course just write it down into a file and run it with node ./script.js
.
Maybe you go one more step and add a hashbang and make it executable,
so on a linux shell you run it with just ./script.js
.
But this way you can not import the file without executing all the code.
Wrapping all the code into a function and executing it if (require.main === module)
helps with that.
You also manage to parse those arguments you need, maybe using one of the available libraries.
- Are you able to also call your function from code with those arguments?
- Do you need to make any async call (like making a request to an API)?
- What about error handling:
try {...} catch (err) {...}
or.then(...).catch(...)
? - Do you have/need one script or many scripts?
Don't regret, runex
was created, because this was just to much time and code
for something that convenient.
- reduce the amount of code that needs to be written to run a module (a javascript file) as a node script
- the module does not (need to) have any special code to make it executable,
including support for
async
functions/promises - convention over configuration
As soon as your module exports a method with the name run
, it is "runnable":
Usage: [npx] runex [options] runnable [args]
Options:
-r, --require <module> 0..n modules for node to require (default: [])
-h, --help output usage information
- it receives (just the relevant) arguments (as strings)
- it can be
async
/ return aPromise
- it can throw (rejected Promises will be treated the same way)
- it is in control of
stdout
(runex
only communicates overstderr
), with one exception:- if you return a value it will be printed to
stdout
(so you don't have to, see goal) iftypeof value === 'object
it will beJSON.stringify
ed.
- if you return a value it will be printed to
Go check some examples.
Of course your can make use of runex
to make your module "executable"
if (require.main === module) {
require('runex').run(module);
}
The above code would make the following differences:
- users of your module can write
node [path/to/]module
instead ofnode runex [path/to/]module
- you are able to customize option parsing
-
https://github.com/DVLP/run-func:
This library was my initial inspiration when searching for an existing solution. But I think not every function is easy to run as a script (just think about the type of the arguments, return types, etc.). So I decided to rely on a naming convention for the executable function. -
if (require.main === module) {...}
:
The "native" way of making a module "executable".
But the tricky part is what needs to be written instead of...
, in every "executable" module.
That's why I listed the first first goal.
BTW: runex
makes use of this mechanism, so you don't need to, but you can of course have both.
Do you know an alternative that should be listed? Create an issue or PR!