Next time you have an idea 💡 "I know... Why don't I write a script to automate this thing?" Actually, you should not, you should write a CLI instead.
CLI has better structure than scripts. CLI uses flags and help text to avoid mistakes. For example:
$ moa --help
Moa makes it easier to run your local node.js apps.
USAGE
$ moa
OPTIONS
-c, --commands=commands [default: start] commands to run.
-h, --help show CLI help
-r, --root=root [default: ../] root path to run.
DESCRIPTION
...
Have some fun
Scripts are messy. And can get out of control.
At Taggun, we run a lot of node.js application. We make APIs for receipt OCR scanning, by the way. So, I recommend oclif: The Open CLI Framework by Heroku.
How to create a new CLI
Install node.js first.
Start by scaffolding
$ npx oclif single moa
? npm package name (moa): moa
$ cd moa
Modify your flags in src\index.js
MoaCommand.flags = {
// add --help flag to show CLI version
help: flags.help({char: 'h'}),
commands: flags.string({char: 'c', description: 'commands to run. Comma-separated.', default: 'start'}),
root: flags.string({char: 'r', description: 'root path to run.', default: '../'}),
}
Modify your description in src\index.js
MoaCommand.description = `Moa makes it easier to run your local node.js apps.
Modify your command in src\index.js
class MoaCommand extends Command {
async run() {
const {flags} = this.parse(MoaCommand)
const commands = flags.commands.split(',')
const {root} = flags
find.file(/(?<!node_modules\/.*)\/package\.json$/, root, files => {
files.forEach(async file => {
const cwd = require('path').dirname(file)
commands.forEach(async command => {
this.log(cwd, `npm run ${command}`)
const npm = spawn('npm', ['run', command], {cwd})
for await (const output of npm.stdout) {
this.log(`${file}: ${output}`)
}
})
})
})
}
}
In this example, you will need to run npm i find
to install find
npm module.
This simple CLI will look for all node.js application in the [root]
and run npm run [command]
. Great if you need to run multiple node.js application to start coding.
Run it
./bin/run -c start -c ../taggun/
Top comments (0)