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. And, CLI uses command flags and help text to prevent you from making silly 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. By the way, we make APIs for receipt OCR scanning. And I recommendĀ oclif: The Open CLI Framework by Heroku for creating and managing CLIs.
How to create a new CLI
InstallĀ node.jsĀ first.
$ npx oclif single moa
? npm package name (moa): moa
$ cd moa
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.
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 folderĀ and runĀ
npm run [command]
. Great if you need to run multiple node.js application to start coding../bin/run -c start -c ../taggun/