什么是 Yargs

如何使用 yargs - 图1

Yargs 是一个很好的命令行程序库,简单地说,它可以让创建一个在控制台中运行的应用程序的过程变得轻而易举。还有什么能让它变得更好呢?它是以海盗为主题的(它的名字叫 YARgs),让它正式成为有史以来最好的工具。

你可能知道其他的 CLI,比如 vue-cli,可以轻松设置一个 Vue.js 项目或 create-react-app,所以这个概念对大多数人来说应该很熟悉。

开始

  1. mkdir yargs_practice
  2. cd yargs_practice
  3. touch yargs.js

初始化项目, 并安装 yargs

  1. npm init -y
  2. npm i yargs

package.json 如下所示:

  1. {
  2. "name": "yargs_practice",
  3. "version": "1.0.0",
  4. "description": "",
  5. "main": "yargs.js",
  6. "scripts": {
  7. "test": "echo \"Error: no test specified\" && exit 1"
  8. },
  9. "keywords": [],
  10. "author": "",
  11. "license": "ISC",
  12. "dependencies": {
  13. "yargs": "^15.3.1"
  14. }
  15. }

使用 vscode 打开当前目录

  1. code .

编辑 yargs.js

  1. const yargs = require("yargs");
  2. const argv = yargs.argv;
  3. console.log(argv);

在终端中运行

  1. node yargs.js add --new thing --old="stuff"

得到如下结果

如何使用 yargs - 图2

yard 可以很方便的拿到命令行参数

继续修改 yargs.js

  1. const yargs = require("yargs");
  2. const argv = yargs
  3. .command("add", "Add a new note")
  4. .command("list", "List all notes")
  5. .help().argv;
  • command 可以增加命令行信息
  • help 方法可以显示帮助信息

在终端中运行

  1. node yargs.js --help

显示如下信息

如何使用 yargs - 图3

yargs 提供了快捷命令方法(alias)让一些命令更简洁

继续修改 yargs.js

  1. const yargs = require("yargs");
  2. const argv = yargs
  3. .command("add", "Add a new note")
  4. .command("list", "List all notes")
  5. .help()
  6. .alias("help", "h").argv;

在终端中运行

  1. node yargs.js -h

会得到和--help 一样的结果

TODO:: option 没看明白

  1. const yargs = require("yargs");
  2. const argv = yargs
  3. .command("add", "Add a new note")
  4. .command("list", "List all notes")
  5. .help()
  6. .alias("help", "h").argv;

如何使用 yargs - 图4

yargs 还支持子命令 用法如下

  1. const yargs = require("yargs");
  2. const argv = yargs
  3. .command("add", "Add a new note", {
  4. title: {
  5. describe: "Title of note",
  6. alias: "t",
  7. demandOption: true,
  8. },
  9. body: {
  10. describe: "Body of note",
  11. alias: "b",
  12. demandOption: true,
  13. },
  14. })
  15. .command("list", "List all notes")
  16. .help()
  17. .option("find")
  18. .alias("help", "h").argv;

add 这个命令增加了子命令 title

  • describe 是这条命令的描述
  • alias 是这条命令的简写
  • demandOption 表示 title 必须传递参数

当我们在终端中执行

  1. node yargs.js add -h

如何使用 yargs - 图5

注意这里有别于 node yargs.js -h 这里展示的是 add 这条命令的具体帮助信息

实例

我们通过一个小的实例来看 yargs 如何使用

我们需要对这个package.json文件做一些调整,因为我们要创建一个 CLI。现在看起来应该是这样的。

  1. {
  2. "name": "yargs_practice",
  3. "version": "1.0.0",
  4. "description": "",
  5. "main": "yargs.js",
  6. "scripts": {
  7. "test": "echo \"Error: no test specified\" && exit 1"
  8. },
  9. "bin": {
  10. "line-count": "./line-count"
  11. },
  12. "keywords": ["cli"],
  13. "preferGlobal": true,
  14. "author": "",
  15. "license": "ISC",
  16. "dependencies": {
  17. "yargs": "^15.3.1"
  18. }
  19. }

以下是需要注意的重要改动。

我们添加了一个 bin 值,它将我们稍后创建的条目文件映射到它的可执行文件名上(你可以设置为任何你想要的名字
我们已经将 preferGlobal 设置为 true,这意味着我们的软件包希望被全局安装(例如通过 npm install -g)。
其他的调整包括改变描述、删除已使用的脚本、添加作者名称等。

创建一个基本的 CLI

Yargs 让解析命令行参数变得非常简单,很多例子项目可以在这里找到。

我们将创建一个基本的 CLI,它可以接收一个文件作为参数并计算它的行数。

要做到这一点,首先创建一个主脚本文件。

  1. touch line-count

编辑这个文件

  1. #!/usr/bin/env node
  2. const argv = require("yargs")
  3. .usage("Usage: $0 <command> [options]")
  4. .help("h")
  5. .alias("h", "help").argv;

让我们把所有的代码逐条逐句的说说。

  1. #!/usr/bin/env node 是一个 shebang 行的实例,它告诉我们的系统用什么解释器来执行该文件
  2. .usage('Usage: $0 <command> [options]')设置当调用 —help 命令时将显示的 CLI 的用法信息。
  3. .help('h') 将帮助命令绑定到选项 h 上。
  4. .alias('h', 'help') 为选项 -h 创建了一个别名,即 --help

与你所见,这第一步是非常简单的,yargs 的语法很直观。

接下来我们要添加count命令。

只需在你已有的 CLI 中添加以下几行。

  1. .command("count", "Count the lines in a file")
  2. .example("$0 count -f foo.js",
  3. "count the lines in the given file")

逐行看看:

  1. .command("count", "count the lines in a file") 创建了一个新的命令,名称为 count,并设置了一个描述。

  2. .example("$0 count -f foo.js", "count the lines in the given file") 创建一个带有描述的例子,当用户调用 —help 选项或者当他们忘记这个命令时,它将显示出来。

这些都很好,但现在运行node line-count计数并没有什么作用,接下来我们需要一个文件名,通过计数并显示其行数来完成 CLI。

添加如下信息

  1. .alias("f", "file")
  2. .nargs("f", 1)
  3. .describe("f", "Load a file")
  4. .demandOption(["f"])

line-count 最后应该是这样的样子。

  1. #!/usr/bin/env node
  2. const argv = require("yargs")
  3. .usage("Usage: $0 <command> [options]")
  4. .command("count", "Count the lines in a file")
  5. .example("$0 count -f foo.js", "count the lines in the given file")
  6. .alias("f", "file")
  7. .nargs("f", 1)
  8. .describe("f", "Load a file")
  9. .demandOption(["f"])
  10. .help("h")
  11. .alias("h", "help").argv;

逐行,解释下新添加的代码

  1. .alias("f", "file") 为-f 选项创建别名 —file。

  2. .nargs("f", 1) 为该选项设置一个参数(文件名),否则显示 —help 菜单。

  3. .description("f", "Load a file")为该选项添加一个描述。

  4. .demandOption([["f"]),因为我们需要一个文件名,所以我们要求选项-f。

最后,让我们把程序的逻辑加上。

  1. // Create stream with the file
  2. const s = fs.createReadStream(argv.file);
  3. var lines = 0;
  4. s.on("data", (buf) => {
  5. // Get the number of lines
  6. lines += buf.toString().match(/\n/g).length;
  7. });
  8. s.on("end", () => {
  9. // Display the number of lines
  10. console.log(lines);
  11. });

就这样,我们来试试。

如何使用 yargs - 图6

到现在为止,我们的程序一直是这样运行的,但如果直接调用它,就会报错。

如何使用 yargs - 图7

我们可以通过使用 npm link 命令将二进制文件(我们之前在 package.json 中定义为 bin)进行全局注册来解决这个问题。

在当前目录下执行

  1. npm link

恭喜 🎉,你现在可以像这样在本地运行你的脚本了。

  1. line-count count -f package.json

如何使用 yargs - 图8

发布 CLI 到 NPM

在部署之前,我们需要在 package.json 中添加一些信息。

  1. "homepage": "YOUR GITHUB REPO OR SITE HERE",
  2. "repository": {
  3. "type": "git",
  4. "url": "git+YOUR GITHUB REPOSITORY HERE"
  5. },
  6. "engines": {
  7. "node": ">=8"
  8. },
  • homepage 和 repository 要填写你自己的 GitHub 项目地址
  • engines 确认 nodejs 版本号,简单地定义了你的项目应该在最小版本的节点上工作。 版本号取决于你用了那些版本的特性。

下面是接下来的步骤。

  • npmjs.com 上创建一个账户(可选,如果有可以忽略)
  • 运行 npm login 命令并输入你的信息
  • 运行 npm publish 命令,它将在几分钟内自动发布。

就是这样! 如果你想在将来更新你的项目,你需要在 package.json 文件中修改它的版本号,然后再次运行发布命令。

参考

  1. Building a CLI with Yargs
  2. How to use Yargs