Bare bones setup. Using NX version 17.
Create the app
npx nx g @nx/node:app --name cli --directory packages/cli --framework none --e2eTestRunner none --unitTestRunner none
Install Commander
npm i -S commander @commander-js/extra-typings
Configure targets
Modify the default build target's development configuration to include "watch": true
.
{
"name": "cli",
"$schema": "../../node_modules/nx/schemas/project-schema.json",
"sourceRoot": "packages/cli/src",
"projectType": "application",
"targets": {
"build": {
"executor": "@nx/esbuild:esbuild",
"outputs": ["{options.outputPath}"],
"defaultConfiguration": "production",
"options": {
"platform": "node",
"outputPath": "dist/packages/cli",
"format": ["cjs"],
"bundle": false,
"main": "packages/cli/src/main.ts",
"tsConfig": "packages/cli/tsconfig.app.json",
"assets": ["packages/cli/src/assets"],
"generatePackageJson": true,
"esbuildOptions": {
"sourcemap": true,
"outExtension": {
".js": ".js"
}
}
},
"configurations": {
"development": {
"watch": true
},
"production": {
"esbuildOptions": {
"sourcemap": false,
"outExtension": {
".js": ".js"
}
}
}
}
},
"lint": {
"executor": "@nx/eslint:lint",
"outputs": ["{options.outputFile}"]
}
},
"tags": []
}
Write a program
// packages/cli/src/main.ts
import { program } from "@commander-js/extra-typings";
program.command("list").action(async () => {
const things = ["one", "two", "three"];
things.forEach((thing) => console.log(thing));
});
program.parse();
Start the development server
npx nx run cli:build:development
This will watch for changes and recompile.
Run the program
node dist/packages/cli/main.js list
Output:
one
two
three
Grow your CLI App from here
Visit the Commander.js reference.
Top comments (1)
That's all good but I'm genuinely curious: why would anyone do that? (I mean increasing setup complexity for a CLI project)