什么是 Yargs
Yargs 是一个很好的命令行程序库,简单地说,它可以让创建一个在控制台中运行的应用程序的过程变得轻而易举。还有什么能让它变得更好呢?它是以海盗为主题的(它的名字叫 YARgs),让它正式成为有史以来最好的工具。
你可能知道其他的 CLI,比如 vue-cli,可以轻松设置一个 Vue.js 项目或 create-react-app,所以这个概念对大多数人来说应该很熟悉。
开始
1 2 3 | mkdir yargs_practice cd yargs_practice touch yargs.js |
初始化项目, 并安装
1 2 | npm init -y npm i yargs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | { "name": "yargs_practice", "version": "1.0.0", "description": "", "main": "yargs.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "yargs": "^15.3.1" } } |
使用 vscode 打开当前目录
1 | code . |
编辑
1 2 3 | const yargs = require("yargs"); const argv = yargs.argv; console.log(argv); |
在终端中运行
1 | node yargs.js add --new thing --old="stuff" |
得到如下结果
yard 可以很方便的拿到命令行参数
继续修改
1 2 3 4 5 | const yargs = require("yargs"); const argv = yargs .command("add", "Add a new note") .command("list", "List all notes") .help().argv; |
command 可以增加命令行信息help 方法可以显示帮助信息
在终端中运行
1 | node yargs.js --help |
显示如下信息
继续修改
1 2 3 4 5 6 | const yargs = require("yargs"); const argv = yargs .command("add", "Add a new note") .command("list", "List all notes") .help() .alias("help", "h").argv; |
在终端中运行
1 | node yargs.js -h |
会得到和
TODO:: option 没看明白
1 2 3 4 5 6 | const yargs = require("yargs"); const argv = yargs .command("add", "Add a new note") .command("list", "List all notes") .help() .alias("help", "h").argv; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | const yargs = require("yargs"); const argv = yargs .command("add", "Add a new note", { title: { describe: "Title of note", alias: "t", demandOption: true, }, body: { describe: "Body of note", alias: "b", demandOption: true, }, }) .command("list", "List all notes") .help() .option("find") .alias("help", "h").argv; |
在
describe 是这条命令的描述alias 是这条命令的简写demandOption 表示title 必须传递参数
当我们在终端中执行
1 | node yargs.js add -h |
注意这里有别于
实例
我们通过一个小的实例来看 yargs 如何使用
我们需要对这个
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | { "name": "yargs_practice", "version": "1.0.0", "description": "", "main": "yargs.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "bin": { "line-count": "./line-count" }, "keywords": ["cli"], "preferGlobal": true, "author": "", "license": "ISC", "dependencies": { "yargs": "^15.3.1" } } |
以下是需要注意的重要改动。
我们添加了一个 bin 值,它将我们稍后创建的条目文件映射到它的可执行文件名上(你可以设置为任何你想要的名字
我们已经将 preferGlobal 设置为 true,这意味着我们的软件包希望被全局安装(例如通过 npm install -g)。
其他的调整包括改变描述、删除已使用的脚本、添加作者名称等。
创建一个基本的 CLI
Yargs 让解析命令行参数变得非常简单,很多例子项目可以在这里找到。
我们将创建一个基本的 CLI,它可以接收一个文件作为参数并计算它的行数。
要做到这一点,首先创建一个主脚本文件。
1 | touch line-count |
编辑这个文件
1 2 3 4 5 | #!/usr/bin/env node const argv = require("yargs") .usage("Usage: $0 <command> [options]") .help("h") .alias("h", "help").argv; |
让我们把所有的代码逐条逐句的说说。
#!/usr/bin/env node 是一个 shebang 行的实例,它告诉我们的系统用什么解释器来执行该文件.usage('Usage: $0 设置当调用 --help 命令时将显示的 CLI 的用法信息。[options]') .help('h') 将帮助命令绑定到选项h 上。.alias('h', 'help') 为选项-h 创建了一个别名,即--help 。
与你所见,这第一步是非常简单的,yargs 的语法很直观。
接下来我们要添加
只需在你已有的 CLI 中添加以下几行。
1 2 3 | .command("count", "Count the lines in a file") .example("$0 count -f foo.js", "count the lines in the given file") |
逐行看看:
-
.command("count", "count the lines in a file") 创建了一个新的命令,名称为 count,并设置了一个描述。 -
.example("$0 count -f foo.js", "count the lines in the given file") 创建一个带有描述的例子,当用户调用 --help 选项或者当他们忘记这个命令时,它将显示出来。
这些都很好,但现在运行
添加如下信息
1 2 3 4 | .alias("f", "file") .nargs("f", 1) .describe("f", "Load a file") .demandOption(["f"]) |
1 2 3 4 5 6 7 8 9 10 11 | #!/usr/bin/env node const argv = require("yargs") .usage("Usage: $0 <command> [options]") .command("count", "Count the lines in a file") .example("$0 count -f foo.js", "count the lines in the given file") .alias("f", "file") .nargs("f", 1) .describe("f", "Load a file") .demandOption(["f"]) .help("h") .alias("h", "help").argv; |
逐行,解释下新添加的代码
-
.alias("f", "file") 为-f 选项创建别名 --file。 -
.nargs("f", 1) 为该选项设置一个参数(文件名),否则显示 --help 菜单。 -
.description("f", "Load a file") 为该选项添加一个描述。 -
.demandOption([["f"]) ,因为我们需要一个文件名,所以我们要求选项-f。
最后,让我们把程序的逻辑加上。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | // Create stream with the file const s = fs.createReadStream(argv.file); var lines = 0; s.on("data", (buf) => { // Get the number of lines lines += buf.toString().match(/\ /g).length; }); s.on("end", () => { // Display the number of lines console.log(lines); }); |
就这样,我们来试试。
到现在为止,我们的程序一直是这样运行的,但如果直接调用它,就会报错。
我们可以通过使用
在当前目录下执行
1 | npm link |
恭喜 ??,你现在可以像这样在本地运行你的脚本了。
1 | line-count count -f package.json |
发布 CLI 到 NPM
在部署之前,我们需要在
1 2 3 4 5 6 7 8 | "homepage": "YOUR GITHUB REPO OR SITE HERE", "repository": { "type": "git", "url": "git+YOUR GITHUB REPOSITORY HERE" }, "engines": { "node": ">=8" }, |
- homepage 和 repository 要填写你自己的 GitHub 项目地址
- engines 确认
nodejs 版本号,简单地定义了你的项目应该在最小版本的节点上工作。 版本号取决于你用了那些版本的特性。
下面是接下来的步骤。
- 在
npmjs.com 上创建一个账户(可选,如果有可以忽略) - 运行
npm login 命令并输入你的信息 - 运行
npm publish 命令,它将在几分钟内自动发布。
就是这样! 如果你想在将来更新你的项目,你需要在
参考
- Building a CLI with Yargs
- How to use Yargs