发布于 2026-01-06 2 阅读
0

使用 yargs 构建 Node.js CLI

使用 yargs 构建 Node.js CLI

照片由Gregory Culmer拍摄,来自Unsplash


作为开发人员,我们每天都会使用命令行工具。我们使用它们来简化工作中的常见任务:

  • 包装
  • 绒毛
  • 构建应用程序
  • 部署应用程序
  • 发布软件包
  • 实现很多事情的自动化……

但这还不是全部。其中很多都与开发无关!以下是命令行应用程序列表。

我开发了一些命令行工具,例如gitmoji-changelog 。它是一个用于生成符合gitmoji提交规范的变更日志的工具。我还为gatsby-cli做出了贡献,它可以帮助开发者使用 React 构建速度极快的网站和应用程序。所有这些工具都是用yargs实现的。

为什么要使用 yargs?

既然Node.js为我们提供了构建 CLI 应用程序所需的所有工具,为什么还要使用yargs?

一个好例子胜过千言万语。让我们来创建一个简单的命令行应用程序。调用它时,它会显示Hello world!……

真是个绝妙的例子!

该命令行工具接受一个参数来覆盖默认world的单词。它还接受一个命名选项times来多次记录消息。

我们将逐步构建它,yargs然后再使用它重构代码库。

首先,我们创建一个index.js包含以下内容的文件。

console.log('Hello world!')
Enter fullscreen mode Exit fullscreen mode

我们使用以下命令执行文件node,并将消息打印到控制台中。

foo@bar:~$ node index.js
Hello world!
Enter fullscreen mode Exit fullscreen mode

好的,参数可以在argv全局变量的属性中找到process。第一个参数是可执行文件的路径,第二个参数是已执行的 JavaScript 文件的路径。

[
  "~/.nvm/versions/node/v10.15.3/bin/node",
  "~/index.js"
]
Enter fullscreen mode Exit fullscreen mode

如果我们使用参数调用命令行界面 (CLI),它将返回此数组的第三个元素。我们通过写入该元素来获取其值process.argv[2],并world在未提供该元素时将其用作默认值。

const args = process.argv

const name = args[2] || 'world'

console.log(`Hello${name}!`)
Enter fullscreen mode Exit fullscreen mode

调用命令行界面,现在可以覆盖了world

foo@bar:~$ node index.js you
Hello you!
Enter fullscreen mode Exit fullscreen mode

事情会变得非常复杂!记住,我们希望添加一个选项,允许多次显示该消息。可选参数通常像这样表示--times 3。它们可以放在你想要的任何位置。

我们首先处理可选参数位于名称参数之后的情况。

const args = process.argv

const name = args[2] || 'world'
const times = args[4] || 1

for (let i = 0;i < times; i++) {
  console.log(`Hello${name}!`)
}
Enter fullscreen mode Exit fullscreen mode

调用命令行界面后,该消息会显示三次!

foo@bar:~$ node index.js you --times 3
Hello you!
Hello you!
Hello you!
Enter fullscreen mode Exit fullscreen mode

如果不提供 name 参数,之前的代码将无法运行。即使将可选参数放在 name 参数之前,它也无法运行。

我们修改代码以处理可选参数位于第一个位置的情况。

// ...
if (args[2] === '--times') {
  name = args[4]
  times = args[3]
} 
// ...
Enter fullscreen mode Exit fullscreen mode

当放在名称之后时,我们保持相同的行为。

// ...
} else if (args[3] === '--times') {
  name = args[2]
  times = args[4]
}
// ...
Enter fullscreen mode Exit fullscreen mode

这里提供了名称参数,但没有提供可选参数。

// ...
} else if (args[2] && args[2] !== '--times') {
  name = args[2]
}
// ...
Enter fullscreen mode Exit fullscreen mode

以下是最终代码。

const args = process.argv
let times = 1
let name = 'world'

if (args[2] === '--times') {
  name = args[4]
  times = args[3]
} else if (args[3] === '--times') {
  name = args[2]
  times = args[4]
} else if (args[2] && args[2] !== '--times') {
  name = args[2]
} 

for (let i = 0;i < times; i++) {
  console.log(`Hello ${name}!`)
}
Enter fullscreen mode Exit fullscreen mode

它有点复杂,不太容易读懂。而且,如果我们添加一个新的位置参数,它就无法正常工作了。

使用 yargs 重构我们的 CLI 应用程序

为了构建一个可维护且可扩展的命令行应用程序,我们将使用yargs。它公开了许多功能,其文档中有详细的描述。我们将使用 `command` 函数它接受四个参数:名称、描述、构建器和处理程序。如果将 `name` 参数设置为 `null`*$0`default`,则使用默认命令。

require('yargs')
  .command('$0 [name]', 'start the server',() => {}, () => {
    console.log('Hello world!')
  })
Enter fullscreen mode Exit fullscreen mode

这段代码稍微复杂一些,仅仅是为了显示一条Hello world!消息。随着代码变得越来越复杂,它会变得更有趣。我们来添加名称参数。它将在构建器参数中完成,该参数是一个函数,它接收 yargs 实例作为参数。我们使用位置函数来描述参数。正如你所看到的,它直接接受一个默认值。

require('yargs')
  .command('$0 [name]', 'start the server',(yargs) => {
    yargs
      .positional('name', {
        describe: 'name to display',
        default: 'world'
      })
  }, () => {
    console.log(`Hello world!`)
  })
Enter fullscreen mode Exit fullscreen mode

参数作为参数传递给处理函数。它是一个对象,每个参数都有一个对应的属性。我们给参数命名name,它的值可以在argv.name该属性中获取。

require('yargs')
  .command('$0 [name]', 'start the server',(yargs) => {
    yargs
      .positional('name', {
        describe: 'name to display',
        default: 'world'
      })
  }, (argv) => {
    console.log(`Hello ${argv.name}!`)
  })
Enter fullscreen mode Exit fullscreen mode

是时候见识一下它的强大之处了。我们使用选项yargs函数添加可选参数,它的 API 与类似。别忘了添加默认值。默认值与原始实现中的相同。timespositionalfor

require('yargs')
  .command('$0 [name]', 'start the server',(yargs) => {
    yargs
      .positional('name', {
        describe: 'name to display',
        default: 'world'
      })
      .option('times', {
        alias: 't',
        type: 'number',
        default: 1,
        description: 'number of times the message is logged'
      })
  }, (argv) => {
    for (let i = 0;i < argv.times; i++) {
      console.log(`Hello ${argv.name}!`)
    }
  })
Enter fullscreen mode Exit fullscreen mode

如您所见,我们无需处理编写 CLI 应用程序的技术复杂性,yargs它为我们处理了这一切。

额外福利:它还附带帮助选项

yargs它会自动为您添加命令help!它使用我们在描述界面时提供的信息。

foo@bar:~$ node index.js --help
yargs.js [name]

start the server

Positionals:
  name  name to display                                        [default: "world"]

Options:
  --help       Print the help                                       [boolean]
  --version    Print the version number                            [boolean]
  --times, -t  number of times the message is logged        [number] [default: 1]
Enter fullscreen mode Exit fullscreen mode

yargsAPI文档齐全,您可以在其中找到更复杂的示例。

一切就绪🙌

现在你可以构建所有你梦寐以求的命令行应用程序了!

我创建了一个存储库,其中包含了本文中提到的所有资源。


非常感谢您的反馈🙏 如果您有任何问题,请在推特上联系我@YvonnickFrin

文章来源:https://dev.to/yvonnickfrin/build-a-node-js-cli-using-yargs-2hd