小龙虾学习基础知识3. Commander.js

5 阅读3分钟

Commander.js 使用指南

本文档基于 warelay 项目中的 Commander.js 使用示例,详细介绍如何使用 Commander.js 创建 CLI 工具。

1. 基本设置

安装 Commander.js

npm install commander

导入和初始化

import { Command } from 'commander';

// 创建 Commander 实例
const program = new Command();

设置程序信息

program
  .name('warelay')
  .description('WhatsApp 中继 CLI 工具(使用 Twilio)')
  .version('1.0.0');

2. 命令定义

基本命令结构

program
  .command('命令名称')
  .description('命令描述')
  .option('-s, --short <type>', '选项描述', '默认值')
  .addHelpText('after', '帮助文本')
  .action(async (options) => {
    // 命令执行逻辑
  });

示例:send 命令

program
  .command('send')
  .description('发送 WhatsApp 消息')
  .requiredOption('-t, --to <number>', '接收者号码(E.164 格式,例如 +15551234567)')
  .requiredOption('-m, --message <text>', '消息正文')
  .option('-w, --wait <seconds>', '等待送达状态(0 表示跳过)', '20')
  .option('-p, --poll <seconds>', '等待时的轮询间隔', '2')
  .addHelpText(
    'after',
    `
示例:
  warelay send --to +15551234567 --message "你好"                # 等待 20 秒确认送达(默认)
  warelay send --to +15551234567 --message "你好" --wait 0       # 发送后即返回
  warelay send --to +15551234567 --message "你好" --wait 60 --poll 3`
  )
  .action(async (opts) => {
    // 命令执行逻辑
  });

3. 选项类型

必需选项

使用 .requiredOption() 定义必需选项:

.requiredOption('-t, --to <number>', '接收者号码')

可选选项

使用 .option() 定义可选选项,并可设置默认值:

.option('-w, --wait <seconds>', '等待送达状态', '20')

选项值类型

  • <number> - 数字类型
  • <text> - 文本类型
  • <port> - 端口号类型
  • 无尖括号 - 布尔类型(存在则为 true)

4. 帮助文本

命令帮助

使用 .addHelpText() 添加额外的帮助文本:

.addHelpText(
  'after',
  `
示例:
  warelay send --to +15551234567 --message "你好"
`
)

自动生成帮助

Commander.js 会自动生成帮助信息,用户可以通过 --help 查看:

warelay --help
warelay send --help

5. 动作处理

异步动作

使用 async 函数处理异步操作:

.action(async (opts) => {
  // 异步操作
  const result = await sendMessage(opts.to, opts.message);
  // 处理结果
});

选项验证

在动作中验证选项值:

.action(async (opts) => {
  const intervalSeconds = Number.parseInt(opts.interval, 10);
  if (Number.isNaN(intervalSeconds) || intervalSeconds <= 0) {
    console.error('轮询间隔必须是正整数');
    process.exit(1);
  }
  // 继续执行
});

6. 参数解析

解析命令行参数

在所有命令定义完成后,调用 parseAsync 解析参数:

program.parseAsync(process.argv);

处理命令行参数

Commander.js 会自动解析命令行参数并传递给对应的动作函数。

7. 完整示例

完整的 CLI 工具结构

import { Command } from 'commander';

const program = new Command();

program
  .name('my-cli')
  .description('我的 CLI 工具')
  .version('1.0.0');

// 定义命令 1
program
  .command('command1')
  .description('命令 1 描述')
  .option('-o, --option <value>', '选项描述', '默认值')
  .action(async (opts) => {
    // 命令 1 逻辑
  });

// 定义命令 2
program
  .command('command2')
  .description('命令 2 描述')
  .requiredOption('-r, --required <value>', '必需选项')
  .action(async (opts) => {
    // 命令 2 逻辑
  });

// 解析参数
program.parseAsync(process.argv);

8. 最佳实践

  1. 命令命名:使用简短、描述性的命令名称
  2. 选项命名:使用有意义的选项名称,遵循 -s, --long 格式
  3. 帮助文本:提供清晰的命令描述和示例
  4. 错误处理:在动作中验证选项值并提供明确的错误信息
  5. 异步处理:对于异步操作使用 async/await
  6. 默认值:为可选选项设置合理的默认值
  7. 类型转换:根据需要转换选项值的类型(如字符串转数字)

9. 实际使用示例

查看帮助

warelay --help

发送消息

warelay send --to +15551234567 --message "你好"

监控消息

warelay monitor --interval 2 --lookback 30

运行 webhook 服务器

warelay webhook --port 45000 --reply "收到!"

自动设置

warelay setup

10. 总结

Commander.js 是一个强大的 CLI 工具构建库,通过以下步骤可以创建功能完整的 CLI 应用:

  1. 导入并初始化 Command 实例
  2. 设置程序基本信息(名称、描述、版本)
  3. 定义命令及其选项
  4. 添加帮助文本和示例
  5. 实现命令动作逻辑
  6. 解析命令行参数

通过合理使用 Commander.js,可以创建出用户友好、功能强大的命令行工具。