CLI-Tools
Regeln
- Commander.js für Argumentanalyse —
.command(), .option(), .argument() mit Beschreibungen
- Interaktive Eingabeaufforderungen:
@clack/prompts (modern, schön) oder inquirer — für Benutzereingaben, wenn Argumente nicht bereitgestellt werden
- Spinner:
ora für langlaufende Operationen — starten, Nachricht aktualisieren, erfolgreich/fehlgeschlagen
- Farben:
chalk für gestaltete Ausgaben — sparsam verwenden: rot für Fehler, grün für Erfolg, gelb für Warnungen, dim für sekundäre Informationen
- Konfigurationsdateien:
cosmiconfig — durchsucht automatisch .toolrc, .toolrc.json, tool.config.js, package.json-Schlüssel
- Exit-Codes:
0 für Erfolg, 1 für allgemeinen Fehler, 2 für Nutzungsfehler — immer process.exit(code)
--help und --version Flags: Commander fügt sie automatisch hinzu — schreiben Sie klare Beschreibungen für jede Option
- Fehlerbehandlung: Fangen Sie Fehler auf der obersten Ebene ab, geben Sie eine benutzerfreundliche Meldung auf stderr aus, beenden Sie mit Code 1
- Veröffentlichung:
bin-Feld in package.json, Shebang #!/usr/bin/env node, "type": "module" für ESM
Muster
#!/usr/bin/env node
import { Command } from "commander";
import * as p from "@clack/prompts";
import ora from "ora";
import chalk from "chalk";
const program = new Command()
.name("my-tool")
.description("Ein CLI, das nützliche Dinge tut")
.version("1.0.0");
program
.command("init")
.description("Ein neues Projekt initialisieren")
.option("-t, --template <name>", "zu verwendende Vorlage", "default")
.action(async (options) => {
p.intro(chalk.bold("Projekt-Setup"));
const name = await p.text({ message: "Projektname?", placeholder: "my-app" });
if (p.isCancel(name)) { p.cancel("Abgebrochen."); process.exit(0); }
const spinner = ora("Projekt wird erstellt...").start();
await createProject(name, options.template);
spinner.succeed(chalk.green("Projekt erstellt!"));
p.outro(`Führe ${chalk.cyan(`cd ${name} && npm install`)} aus`);
});
program.parse();
Vermeiden
- Fehler auf stdout ausgeben — verwenden Sie
console.error() oder process.stderr.write() für Fehler
- Beenden ohne Code bei Fehlschlag — immer
process.exit(1), damit Skripte und CI den Fehler erkennen
- Wände aus unformatiertem Text — verwenden Sie chalk-Farben, Abschnitte und Leerraum für Lesbarkeit
- Interaktive Eingabe ohne Flag-Alternative erzwingen — unterstützen Sie immer
--flag-Überschreibungen für CI/Scripting
- Shebang
#!/usr/bin/env node vergessen — ohne ihn funktionieren npx und globale Installationen nicht