日常开发中,编写 Node.js 命令行工具来完成一些小任务是很常见的操作。其编写也不难,和日常编写 Node.js 代码并无二致。

package.json 中的 bin 字段

一个 npm 模块,如果在 package.json 中指定了 bin 字段,那说明该模块提供了可在命令行执行的命令,这些命令就是在 bin 字段中指定的。

package.json

{
"bin": {
"myapp": "./cli.js"
}
}

程序安装后会可在命令行执行 myapp 命令,实际执行的就是指定的这个 cli.js 文件。如果是全局安装,会将这个目标 js 文件映射到 prefix/bin 目录下,而如果是在项目中安装,则映射到 ./node_modules/.bin/ 目录下。

比如上面的示例,全局安装后会将 cli.js 映射到 /usr/local/bin/myapp 目录下。

# 查看项目中安装的所有可执行模块
$ ll node_modules/.bin
...
webpack -> ../webpack/bin/webpack.js
...

如果你的 npm 包只提供了一个可执行的命令,可直接将 bin 字段设置为目标文件,此时命令行中可执行的 CLI 命令名为 npm 包名(即 name 字段)。

{
"name": "my-program",
"version": "1.2.5",
"bin": "./path/to/program"
}

所以上面的配置和下面这个配置是等效的。

{
"name": "my-program",
"version": "1.2.5",
"bin": {
"my-program": "./path/to/program"
}
}

执行:

$ my-program 

CLI 命令的编写

为项目添加 README 文件是很常见的操作,每次都从零开始是没必要的。这时候就可以通过创建一个 README 模板,然后写一个 CLI 工具来生成到项目中。这样,将工具安装到全局或通过 npx 就可以方便地完成 README 文件的创建。

$ npx mkreadme
README.md created

初始化项目

$ npm init -y

修改 package.json 文件为如下内容:

{
"name": "mkreadme",
"bin": "./cli.js",
"version": "0.1.0",
"license": "MIT"
}

创建入口文件

$ touch cli.js

入口文件即 bin 字段所指向的文件,它可以是任何文件名,只需要在行首指定运行环境即可。Node.js 的 CLI 命令,期望的运行环境当然是 Node.js。

cli.js

 #!/usr/bin/env node
// 其他代码...

然后添加我们的功能代码,从远端获取一个 README 模板文件到本地。

cli.js

#!/usr/bin/env node

const fs = require("fs");

const https = require("https"); const TEMPLATE_FILE =

"https://raw.githubusercontent.com/wayou/readme-template/master/README.md"; const file = fs.createWriteStream("README.md");

https.get(TEMPLATE_FILE, resposne => {

resposne.pipe(file);

console.log("README.md created");

});

这里,我们将模板文件放远端的一个位置然后通过网络请求下载下来,而不是直接放到 npm 模块中。这样做的好处是后面可以随时更新我们的模板文件而无须重新发布这个 npm 模块。

调试

通过在当前开发目录进行 link 操作可进行本地调试。

$ npm link
link 操作的输出信息
npm WARN mkreadme@0.1.0 No description
npm WARN mkreadme@0.1.0 No repository field. up to date in 3.435s

found 0 vulnerabilities /Users/wayou/.nvm/versions/node/v11.14.0/bin/mkreadme -> /Users/wayou/.nvm/versions/node/v11.14.0/lib/node_modules/mkreadme/cli.js

/Users/wayou/.nvm/versions/node/v11.14.0/lib/node_modules/mkreadme -> /Users/wayou/Documents/dev/github/mkreadme

然后就可以在任何地方执行刚刚创建的 CLI 命令了。

$ mkreadme
README.md created

参数的获取

让命令支持参数可以实现更加灵活的功能。通过 process.argv 在代码中能够获取到来自命令行的输入。但需要注意它返回的参数列表中前两位是 Node.js 的路径和当前项目的路径,从第三个元素开始才是命令中用户输入的数据。

#!/usr/bin/env node

const fs = require("fs");

const https = require("https"); const TEMPLATE_FILE =

"https://raw.githubusercontent.com/wayou/readme-template/master/README.md"; + const [, , ...args] = process.argv; const file = fs.createWriteStream("README.md");

+ const url = args[0] || TEMPLATE_FILE;

+ https.get(url, resposne => {

resposne.pipe(file);

console.log("README.md created");

});

通过添加参数的支持,我们可以让使用者手动指定一个模板地址以下载对应的模板文件。

发布

最后一步就是发布出去,这样所有人就能安装使用了。

$ npm publish --access public

安装与使用

$ npm i -g mkreadme
$ mkreadme
README.md created

除了像上面将命令安装到全局使用外,个人更加推荐的方式是通过 npxnpx 会自动查找本机是否有安装相应模块,如果没有的话,自动去远端查找并执行。通过 npx 就不用安装到本地,每次运行都可以使用远端最新的版本。

$ npx mkreadme
README.md created

后续的优化

示例中只实现了基本的功能,作为一个功能健全的实用工具,可以做以下的优化:

  • 生成时做重名判断,如果已经存在 README 文件则提示是否覆盖。
  • 文件下载和创建过程中的异常处理及提示。
  • 提供并打印帮助信息,对使用者更加友好。
  • 对输出进行格式化,高亮输出相关信息,使信息更易读。

完整的示例

上面示例中的代码可在 mkreadme 这个仓库中找到。同时也发布到了 npm,可直接使用体验该工具。

三方工具

命令行工具能够打印帮助和使用信息是很重要的,如果自己输出的话,会面临格式化这些内容的麻烦。

如果提供的参数很多,解析处理用户输入的参数也是件很麻烦的事。

像参数校验,错误提示及帮助信息的输出,这些命令行工具基本的功能已经有三方库比较成熟地解决了,比如 commander.js。通过这个库可方便地编写更加复杂的命令行工具。

至于将输出信息进行高亮加彩色进行展示,也有相应三方库比如 chalk

相关资源

Node.js 命令行工具的编写的更多相关文章

  1. 一个最简单 node.js 命令行工具

    一个最简单 node.js 命令行工具 node.js cli $ node cli.js xyz # OR $ node cli xyz 接受参数 process.argv js "use ...

  2. Node.js 命令行程序开发资料

    Node.js 命令行程序开发教程http://www.ruanyifeng.com/blog/2015/05/command-line-with-node.html用Node.js创建命令行工具ht ...

  3. Node.js 命令行程序开发教程

    nodejs开发命令行程序非常方便,具体操作方式查看下面几篇文章 http://www.ruanyifeng.com/blog/2015/05/command-line-with-node.html ...

  4. Node.js 命令行程序开发教程 ---------http://www.ruanyifeng.com/blog/2015/05/command-line-with-node.html

    五.yargs 模块 shelljs 只解决了如何调用 shell 命令,而 yargs 模块能够解决如何处理命令行参数.它也需要安装. $ npm install --save yargs yarg ...

  5. node命令行工具—cf-cli

    音乐分享: 钢心 - <龙王> 初喜<冠军>后喜<龙王> (PS:听一次钢心乐队的演出后采访才知道 “龙王”隐喻的是一起喝酒的老铁....) ——————————— ...

  6. 从零开始打造个人专属命令行工具集——yargs完全指南

    前言 使用命令行程序对程序员来说很常见,就算是前端工程师或者开发gui的,也需要使用命令行来编译程序或者打包程序 熟练使用命令行工具能极大的提高开发效率,linux自带的命令行工具都非常的有用,但是这 ...

  7. 如何用Node编写命令行工具

    0. 命令行工具 当全局安装模块之后,我们可以在控制台下执行指定的命令来运行操作,如果npm一样.我把这样的模块称之为命令行工具模块(如理解有偏颇,欢迎指正) 1.用Node编写命令行工具 在Node ...

  8. Node.js躬行记(3)——命令行工具

    一.自定义 创建一个空目录,然后通过npm init命令初始化package.json文件,并按提示输入相关信息或直接回车使用默认信息,生成的内容如下所示. { "name": & ...

  9. 微软开放技术发布针对 Mac 和 Linux 的更新版 Azure Node.JS SDK 和命令行工具

    发布于 2013-12-04 作者 Eduard Koller 这次为我们使用Linux 的朋友带来了更多关于部署云上虚拟机的消息.今天,微软开放技术有限公司 (MS Open Tech),想与大家分 ...

随机推荐

  1. Python集合set

    集合 set 集合是无序的 集合的值是唯一的 求两个集合的关系: list1 = [1,4,5,7,3,6,7,9] list2 = set([2,6,0,66,22,8,4]) list3 = se ...

  2. 转[@SuppressWarnings详解]

    背景知识:       从JDK5开始提供名为Annotation(注释)的功能,它被定义为JSR-175规范.注释是以“@注释名”在代码中存在的,还可以添加一些参数 值,例如:@SuppressWa ...

  3. InfluxDB介绍

    InfluxDB介绍 InfluxDB用Go语言编写的一个开源分布式时序.事件和指标数据库,和传统是数据库相比有不少不同的地方. 类似的数据库有Elasticsearch.Graphite等. 特点 ...

  4. orcl数据库命令行怎么导入dmp格式的文件

    2018-05-23 1.创建空间 以system的身份登陆orcl 打开SQL Window界面,输入以下命令create tablespace SGXC(表空间的名字)datafile 'D:/S ...

  5. ASP.NET Core Identity Hands On(2)——注册、登录、Claim

    上一篇文章(ASP.NET Core Identity Hands On(1)--Identity 初次体验)中,我们初识了Identity,并且详细分析了AspNetUsers用户存储表,这篇我们将 ...

  6. python strip()函数和Split函数的用法总结

    strip函数原型 声明:s为字符串,rm为要删除的字符序列. 只能删除开头或是结尾的字符或是字符串.不能删除中间的字符或是字符串. s.strip(rm) 删除s字符串中开头.结尾处,位于 rm删除 ...

  7. appium--xpath定位元素用法

    一.xpath的使用场景: 自动化测试中经常对元素进行操作时,如果存在id.name.content_desc时,可通过appium框架提供的方法find_element_by_id/name/tag ...

  8. 面试题之小炼牛刀zip,lambda,map

    # 现有两元祖,(('a'),('b')),(('c'),('d'))# 请使用python中匿名函数生成列表[{'a':'c'},{'b':'d'}]t1=(('a'),('b'))t2=(('c' ...

  9. java泛型中使用的排序算法——归并排序及分析

    一.引言 我们知道,java中泛型排序使用归并排序或TimSort.归并排序以O(NlogN)最坏时间运行,下面我们分析归并排序过程及分析证明时间复杂度:也会简述为什么java选择归并排序作为泛型的排 ...

  10. 为啥程序会有bug?

    如果这是第二次看到我的文章,欢迎右侧扫码订阅我哟~