为你的团队打造一个 Node CLI 工具吧

想想你的团队会有一些重复性工做吗?思考一下,CLI 工具也许能够减小掉许多重复工做,统一合做规范,提高工做效率。node

为何是 Node

Node 拥有最为庞大的生态社区,数十万的 Package,其中有许多 Package 是专门为建强大的 CLI 工具打造的。在社区生态的帮助下,你能够更快速构建更强大的 CLI 工具。同时,在 NPM、Yarn 等 Package 管理工具的帮助下,你也能够快速的分发的你的 CLI 工具,让你的用户更简单的使用你的 CLI 工具。git

快速开始

初始化项目github

mkdir cli-tool && cd cli-tool
npm init --yes
复制代码

建立 src/cli.js,写入以下内容:npm

// src/cli.js
module.exports = function cli() {
  // 打印命令参数
  console.log(process.argv);
};
复制代码

建立 bin/cli.js 文件,这是 CLI 工具的入口文件,写入以下内容:json

#!/usr/bin/env node
const cli = require("../src/cli");

cli();
复制代码

重点:修改 package.json ,写入 bin 字段,添加 cli 命令数组

{
  "name": "cli-tool",
  "version": "1.0.0",
  "description": "",
  "main": "src/cli.js",
  "bin": {
    "cli": "bin/cli.js"
  },
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
复制代码

在项目根目录下,运行:bash

npm link
复制代码

在终端中输入 cli 命令,便可打印出以下相似内容:app

[
  '/Users/xx/.nvm/versions/node/v12.16.2/bin/node',
  '/Users/xx/.nvm/versions/node/v12.16.2/bin/cli'
]
复制代码

至此,一个简单的 Node CLI 工具就完成了。工具

基本原理

bin

NPM 实现了将 Package 中的可执行文件添加全局 PATH 中的能力,当在 package.json 文件中添加 bin 字段时,NPM 会将 bin 声明的文件连接(软连接)到 bin 目录中(全局可用),或者 ./node_modules/bin/(本地可用)。动画

以下面的 bin 建立 /usr/local/bin/myappcli.js 的软连接:

{ "bin" : { "myapp" : "./cli.js" } }
复制代码

同时,咱们要在 bin 声明的文件的开头添加 #!/usr/bin/env node 声明,确保系统会用 Node 执行此文件。

npm link

npm link 命令会建立当前 Package 到 Gloabl 的软连接,使当前 Package 在全局可用,相似虚拟的 npm i --global packae命令,在本地调试时十分有用。

实践

参数解析

CLI 工具的基本能力就是要解析用户输入的 CLI 命令与参数,实现相关功能。Node 的 process.argv 数组包含了 Node 进程被启动时传入的命令行参数,经过解析 process.argv 数组便可,社区中相关的 Package 也比较多,如:yargsminimist 等。

这里推荐使用 [commander](https://github.com/tj/commander.js) 构建你的 CLI 工具,commander 是一个较为完善的 Node CLI 解决方案,拥有解析输入参数、关联处理逻辑、输出命令提示等功能。只有当 commander 的功能没法知足你的需求时,才建议你尝试本身处理命令参数解析。

交互输入

在某些状况下,CLI 工具可能须要使用交互式输入,如输入密码时,这种状况不适合直接经过参数输入。简单的输入时,能够直接 Node 的 readline 模块:

const readline = require("readline");
const question = ["请输入您的姓名", "请输入您的年龄"];
const result = [];

const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout,
  prompt: `?${question[0]} `,
});

rl.prompt();

rl.on("line", (line) => {
  result.push(line.trim());
  const max = result.length;
  if (max === question.length) {
    rl.close();
  }
  rl.setPrompt(`?${question[max]} `);
  rl.prompt();
}).on("close", () => {
  console.log(`谢谢参与问答 *** 姓名: ${result[0]} 年龄: ${result[1]}`);
  process.exit(0);
});
复制代码

当须要比较复杂的交互时,如列表选择时,就须要使用社区中的 Package 了。这里推荐 enquirer,功能较为强大,以下:

发布

最后,你能够经过 NPM 将你的 Node CLI 工具快速分发出去:

# 登录 npm
npm adduser

# 打 Tag
npm tag v1.0.0

# 发布
npm publish
复制代码

推荐

相关文章
相关标签/搜索