📜  Node.js Yargs 模块(1)

📅  最后修改于: 2023-12-03 15:17:56.352000             🧑  作者: Mango

Node.js Yargs 模块

Yargs是一个Node.js的命令行解析器,它可以让开发者更容易地构建命令行界面(CLI)应用程序。它提供了许多功能,如参数解析,命令解析,选项自动提示,校验等。因此,如果你想要构建一个powerful的CLI工具,那么Yargs绝对是一个不错的选择。

安装

在使用Yargs之前,你需要先安装它。你可以使用npm进行安装,它是Node.js的默认包管理器。

命令行输入:

npm install yargs
基础使用

下面是一个最基本的使用示例:

const yargs = require('yargs');

yargs.command({
  command: 'hello <name>',
  describe: 'Say hello to someone',
  builder: {
    title: {
      describe: 'Person title',
      type: 'string'
    }
  },
  handler(argv) {
    console.log(`Hello ${argv.title ? argv.title + ' ' : ''}${argv.name}!`);
  }
});

yargs.parse();

当你在命令行中输入node index.js hello John --title Mr时,输出结果为:

Hello Mr John!

在这个示例中,我们使用command方法定义了一个名为hello的命令,它接受一个名为name的参数,并有一个builder定义了一个名为title的选项。

handler函数是命令被调用时的回调函数。在这个例子中,它简单地输出一条“Hello”的消息,其中包含了传入的titlename参数。

参数解析

Yargs的参数解析功能非常强大。你可以指定参数的类型,描述,别名等。下面是一些常用的参数选项:

  • alias: 选项的别名
  • describe: 选项的描述
  • type: 选项的类型
  • demandOption: 是否必须传入该选项
  • default: 选项的默认值
  • array: 是否将该选项解析为一个数组
  • choices: 选项可接受的值列表
  • coerce: 提供自定义的选项解析函数

下面是一个复杂一些的例子,展示了一些更高级的选项用法:

const yargs = require('yargs');

yargs.command({
  command: 'serve <port>',
  describe: 'Start the server',
  builder: {
    secure: {
      alias: 's',
      describe: 'Use HTTPS',
      type: 'boolean',
      default: false
    },
    cert: {
      describe: 'Path to SSL certificate',
      type: 'string',
      implies: 'key'
    },
    key: {
      describe: 'Path to SSL key',
      type: 'string',
      implies: 'cert'
    },
    headers: {
      describe: 'Additional HTTP headers',
      type: 'array',
      default: []
    }
  },
  handler(argv) {
    console.log(`Starting server on port ${argv.port}`);
    if (argv.secure) {
      console.log('Using HTTPS');
      console.log(`SSL certificate: ${argv.cert}`);
      console.log(`SSL key: ${argv.key}`);
    } else {
      console.log('Using HTTP');
    }
    if (argv.headers.length > 0) {
      console.log('Additional headers:');
      argv.headers.forEach(header => console.log(`- ${header}`));
    }
  }
});

yargs.parse();

在这个例子中,我们定义了一个名为serve的命令,它有一个必填参数port和一些选项。其中,secure选项有一个别名s,并且它是一个布尔类型,如果不传入则默认值为false;headers选项是一个字符串数组类型,如果没有传入则默认值为空数组;certkey选项都是字符串类型,同时cert选项会隐含需要传入key选项。

这个例子中还使用了一个特殊的选项implies。这个选项表示如果传入了当前选项,则必须同时传入implies中指定的选项。

校验

Yargs还提供了一些内置的校验功能,可以帮助你快速地验证用户传入的参数是否符合要求。下面是一些内置的校验器:

  • check: 校验函数,会在最后执行
  • coerceArg: 参数解析函数
  • coerceArgs: 命令行参数解析函数
  • demandOption: 验证选项是否必须传入
  • demandCommand: 验证是否传入了正确的命令
  • conflicts: 验证选项之间是否互斥
const yargs = require('yargs');

yargs.command({
  command: 'serve <port>',
  describe: 'Start the server',
  builder: {
    secure: {
      alias: 's',
      describe: 'Use HTTPS',
      type: 'boolean'
    },
    cert: {
      describe: 'Path to SSL certificate',
      type: 'string'
    },
    key: {
      describe: 'Path to SSL key',
      type: 'string'
    },
    headers: {
      describe: 'Additional HTTP headers',
      type: 'array',
      default: []
    }
  },
  check(argv) {
    if (argv.secure && !argv.cert) {
      throw new Error('If --secure is provided, --cert is also required');
    }
    if (argv.secure && !argv.key) {
      throw new Error('If --secure is provided, --key is also required');
    }
    if (argv.port < 1 || argv.port > 65535) {
      throw new Error('Invalid port number');
    }
    return true;
  },
  handler(argv) {
    console.log(`Starting server on port ${argv.port}`);
    if (argv.secure) {
      console.log('Using HTTPS');
      console.log(`SSL certificate: ${argv.cert}`);
      console.log(`SSL key: ${argv.key}`);
    } else {
      console.log('Using HTTP');
    }
    if (argv.headers.length > 0) {
      console.log('Additional headers:');
      argv.headers.forEach(header => console.log(`- ${header}`));
    }
  }
});

yargs.strict().parse();

在这个例子中,我们定义了一个check函数,可以在处理前对传入的参数进行一些校验。如果校验失败,可以通过抛出一个Error实例来中止程序执行。

我们还加入了一个strict选项,它会在不正确的命令行调用时抛出一个错误并终止程序执行。

让CLI更人性化

Yargs还提供了一些让CLI看起来更友好的功能。比如自动完成功能,可以让用户更轻松地输入命令。

const yargs = require('yargs');
const fs = require('fs');
const path = require('path');

yargs.command({
  command: 'serve <port>',
  describe: 'Start the server',
  builder: {
    secure: {
      alias: 's',
      describe: 'Use HTTPS',
      type: 'boolean'
    },
    cert: {
      describe: 'Path to SSL certificate',
      type: 'string'
    },
    key: {
      describe: 'Path to SSL key',
      type: 'string'
    },
    headers: {
      describe: 'Additional HTTP headers',
      type: 'array',
      default: []
    }
  },
  suggest(keywords) { //这里定义自动完成功能的提词函数
    if (keywords.length === 1 && keywords[0].startsWith('-')) {
      return yargs.getOptions().help;
    }
    const files = fs.readdirSync('.').map(file => path.basename(file, path.extname(file)));
    const commands = yargs.getCommands().map(command => command.split(' ')[0]);
    return [...files, ...commands];
  },
  check(argv) {
    if (argv.secure && !argv.cert) {
      throw new Error('If --secure is provided, --cert is also required');
    }
    if (argv.secure && !argv.key) {
      throw new Error('If --secure is provided, --key is also required');
    }
    if (argv.port < 1 || argv.port > 65535) {
      throw new Error('Invalid port number');
    }
    return true;
  },
  handler(argv) {
    console.log(`Starting server on port ${argv.port}`);
    if (argv.secure) {
      console.log('Using HTTPS');
      console.log(`SSL certificate: ${argv.cert}`);
      console.log(`SSL key: ${argv.key}`);
    } else {
      console.log('Using HTTP');
    }
    if (argv.headers.length > 0) {
      console.log('Additional headers:');
      argv.headers.forEach(header => console.log(`- ${header}`));
    }
  }
});

yargs.strict().parse();

在这个例子中,我们定义了一个suggest方法,这个方法接受一个关键词的数组作为参数,返回一个数组,这个数组中是可以匹配到的结果列表。在这个例子中,我们简单地返回目录中的所有文件名和命令列表。

总结

使用Yargs可以很大地提高我们CLI工具的开发效率,让程序员可以更专注于业务逻辑的实现,而不用花费过多的精力在命令行参数解析方面。希望这篇文章对你有所帮助。