|
| 1 | +# node命令行工具开发 |
| 2 | + |
| 3 | +> NodeJs有许多命令行工具。它们全局安装,并提供一个命令供我们使用,完成相应的功能。 现在我们就用node来开发一个实用的命令行小工具 |
| 4 | +
|
| 5 | +## 一.初探 |
| 6 | + |
| 7 | +### 一个最简单的命令行工具 |
| 8 | + |
| 9 | +1.首先我们新建一目录,然后执行`npm init`生成package.json文件 |
| 10 | + |
| 11 | +2.新建一bin目录并在目录下创建一个hi.js |
| 12 | + |
| 13 | +```javascript |
| 14 | +#! /usr/bin/env node |
| 15 | +console.log("hi") |
| 16 | +``` |
| 17 | + |
| 18 | +执行`node hi.js`我们可以看到终端输出hi。。当然这并不是我们要的命令行工具,我们需要直接运行`hi`就可出现结果 |
| 19 | + |
| 20 | +3.现在我们告诉npm可执行文件是哪个,在package.json里添加如下信息: |
| 21 | + |
| 22 | +```json |
| 23 | + "bin": { |
| 24 | + "hi": "bin/hi.js" |
| 25 | + } |
| 26 | +``` |
| 27 | + |
| 28 | +4. `npm link` |
| 29 | + |
| 30 | + 现在我们执行`npm link`启用命令行,现在再试试在终端直接输入`hi`命令,这次我们可以如愿见到结果 |
| 31 | + |
| 32 | +### 处理参数 |
| 33 | + |
| 34 | +命令行参数可通过系统变量`process.argv`获取。 *process.argv返回一个数组 第一个是node 第二个是脚本文件 第三个是输入的参数,*`process.argv[2]`开始得到才是真正的参数部分 |
| 35 | + |
| 36 | +```javascript |
| 37 | + #! /usr/bin/env node |
| 38 | + |
| 39 | +let argv = process.argv.slice(2) |
| 40 | +let yourName = argv[0] |
| 41 | +console.log(`hi, ${yourName}!`) |
| 42 | + |
| 43 | +// 执行 hi cosyer |
| 44 | +// hi, cosyer! |
| 45 | +``` |
| 46 | + |
| 47 | +### Commander.js |
| 48 | +对于参数处理,我们一般使用[commander](https://github.com/tj/commander.js),commander是一个轻巧的nodejs模块,提供了用户命令行输入和参数解析强大功能如:自记录代码、自动生成帮助、合并短参数(“ABC”==“-A-B-C”)、默认选项、强制选项、命令解析、提示符 |
| 49 | + |
| 50 | + ```bash |
| 51 | + $ npm install commander --save |
| 52 | + ``` |
| 53 | + |
| 54 | +```javascript |
| 55 | +#!/usr/bin/env node |
| 56 | + |
| 57 | +/** |
| 58 | + * Module dependencies. |
| 59 | + */ |
| 60 | + |
| 61 | +var program = require('commander') |
| 62 | + |
| 63 | +program |
| 64 | + .version('0.0.1') |
| 65 | + .option('-p, --peppers', 'Add peppers') |
| 66 | + .option('-P, --pineapple', 'Add pineapple') |
| 67 | + .option('-b, --bbq-sauce', 'Add bbq sauce') |
| 68 | + .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble') |
| 69 | + .parse(process.argv) |
| 70 | + |
| 71 | +console.log('you ordered a pizza with:') |
| 72 | +if (program.peppers) console.log(' - peppers') |
| 73 | +if (program.pineapple) console.log(' - pineapple') |
| 74 | +if (program.bbqSauce) console.log(' - bbq') |
| 75 | +console.log(' - %s cheese', program.cheese) |
| 76 | +``` |
| 77 | +### Commander API |
| 78 | +- `Option()`: 初始化自定义参数对象,设置“关键字”和“描述” |
| 79 | +- `Command()`: 初始化命令行参数对象,直接获得命令行输入 |
| 80 | +- `Command#command()`: 定义一个命令名字 |
| 81 | +- `Command#action()`: 注册一个callback函数 |
| 82 | +- `Command#option()`: 定义参数,需要设置“关键字”和“描述”,关键字包括“简写”和“全写”两部分,以”,”,”|”,”空格”做分隔。 |
| 83 | +- `Command#parse()`: 解析命令行参数argv |
| 84 | +- `Command#description()`: 设置description值 |
| 85 | +- `Command#usage()`: 设置usage值 |
| 86 | +- 更多参考 [commander官网](http://tj.github.io/commander.js/) |
| 87 | + |
| 88 | +除了commander外,[yargs](http://yargs.js.org/)也是一个优秀的命令行参数处理模块 |
| 89 | + |
| 90 | +## 二.开发命令行翻译工具 |
| 91 | + |
| 92 | +### 1.新建并初始化项目 |
| 93 | +新建 文件夹translator/进入目录下执行`npm init` 生成package.json文件 |
| 94 | +```bash |
| 95 | +npm install commander superagent cli-table2 --save |
| 96 | +``` |
| 97 | +- *[cli-table2](http://npm.taobao.org/package/cli-table2)命令行表格输出* |
| 98 | +- *[superagent](http://visionmedia.github.io/superagent/)用于http请求* |
| 99 | + |
| 100 | +新建bin/translator.js文件,并加入package.json文件中 |
| 101 | +```json |
| 102 | + "bin": { |
| 103 | + "translator": "bin/translator.js" |
| 104 | + }, |
| 105 | +``` |
| 106 | +然后 |
| 107 | +```bash |
| 108 | +npm link |
| 109 | +``` |
| 110 | + |
| 111 | +这里我们会用到[有道API](http://fanyi.youdao.com/openapi?path=data-mode) |
| 112 | +一切准备就绪我们就可以进行编码了 |
| 113 | + |
| 114 | +### 2.coding |
| 115 | +*由于代码量很小,这里就直接贴代码,在代码中以注释讲解* |
| 116 | +```javascript |
| 117 | +#! /usr/bin/env node |
| 118 | +// 引入需要的模块 |
| 119 | +const program = require('commander') |
| 120 | +const Table = require('cli-table2') // 表格输出 |
| 121 | +const superagent = require('superagent') // http请求 |
| 122 | +// 初始化commander |
| 123 | +program |
| 124 | + .allowUnknownOption() |
| 125 | + .version('0.0.1') |
| 126 | + .usage('translator <cmd> [input]') |
| 127 | + |
| 128 | +// 有道api |
| 129 | +const API = 'http://fanyi.youdao.com/openapi.do?keyfrom=toaijf&key=868480929&type=data&doctype=json&version=1.1' |
| 130 | + |
| 131 | +// 添加自定义命令 |
| 132 | +program |
| 133 | + .command('query') |
| 134 | + .description('翻译输入') |
| 135 | + .action(function(word) { |
| 136 | + // 发起请求 |
| 137 | + superagent.get(API) |
| 138 | + .query({ q: word}) |
| 139 | + .end(function (err, res) { |
| 140 | + if(err){ |
| 141 | + console.log('excuse me, try again') |
| 142 | + return false |
| 143 | + } |
| 144 | + let data = JSON.parse(res.text) |
| 145 | + let result = {} |
| 146 | + |
| 147 | + // 返回的数据处理 |
| 148 | + if(data.basic){ |
| 149 | + result[word] = data['basic']['explains'] |
| 150 | + }else if(data.translation){ |
| 151 | + result[word] = data['translation'] |
| 152 | + }else { |
| 153 | + console.error('error') |
| 154 | + } |
| 155 | + |
| 156 | + // 输出表格 |
| 157 | + let table = new Table() |
| 158 | + table.push(result) |
| 159 | + console.log(table.toString()) |
| 160 | + }) |
| 161 | + }) |
| 162 | + |
| 163 | +// 没有参数时显示帮助信息 |
| 164 | +if (!process.argv[2]) { |
| 165 | + program.help(); |
| 166 | + console.log(); |
| 167 | +} |
| 168 | + |
| 169 | +program.parse(process.argv) |
| 170 | +``` |
| 171 | + |
| 172 | +现在在终端中愉快的使用`translator`了 |
| 173 | + |
| 174 | +``` |
| 175 | +$ translator |
| 176 | +Usage: translator <cmd> [input] |
| 177 | + Commands: |
| 178 | + query 翻译输入 |
| 179 | + Options: |
| 180 | + -h, --help output usage information |
| 181 | + -V, --version output the version number |
| 182 | +``` |
| 183 | + |
| 184 | +## 三.小结 |
| 185 | + |
| 186 | +1. 了解nodeJs 可执行脚本 |
| 187 | +2. 了解命令行参数解析 |
| 188 | +3. 了解commander,cli-table2,superagent等第三方模块 |
| 189 | + |
| 190 | +*抛砖引玉,更多请参考各个模块的官方示例及API文档* |
| 191 | + |
| 192 | +### 相关链接 |
| 193 | +- [CommandJs](http://tj.github.io/commander.js/#Command.prototype.parseExpectedArgs) |
| 194 | +- [cli-table2](http://npm.taobao.org/package/cli-table2) |
| 195 | +- [superagent](http://visionmedia.github.io/superagent/) |
| 196 | +- [Node.js 命令行程序开发教程-阮一峰](http://www.ruanyifeng.com/blog/2015/05/command-line-with-node.html) |
| 197 | +- [Commander写自己的Nodejs命令-粉丝日志](http://blog.fens.me/nodejs-commander/) |
0 commit comments