[TOC]
## process.argv
process是node中的一个模块,通过访问process.argv我们能轻松愉快的接收通过命令执行node程序时候所传入的参数。
>[info] argv翻译成中文意思是:命令行变元数组。
这是什么意思呢?我们都在命令行窗口中使用过`npm`命令来进行包的下载,在使用npm命令的时候我们还能进行一些传参,像要下载的包的名字啊,是开发依赖还是生产依赖啊。
这些所**传的参数**+**node.exe绝对路径**+**node所执行文件的绝对路径**所组成的数组 = `process.argv`。它不止包含所传的参数还包含另外两个东东作为数组成员,故称之为**变元**数组。
### 示例1
```
// 文件p1.js中
console.log(process.argv);
>>>命令行中输入
node p1.js --a -b c
<<< 输出
E:\w>node p1.js --a -b c
[ 'C:\\Program Files\\nodejs\\node.exe',
'E:\\w\\p1.js',
'--a',
'-b',
'c' ]
```
## 批处理文件
批处理文件,顾名思义,它能达到通过只执行一个文件从而执行多条node命令的效果,它能极大的简化我们在命令行中的输入,我们**只需要输入批处理文件的名字,甚至不需要输 `node`这个前缀**。
批处理文件在不同的操作系统下是不一样的,主要分为:
- window下的批处理文件
- 类linux下的批处理文件
### windows中的批处理文件
windows中的批处理文件后缀名为`.bat`。
```
//hello.bat文件中
node p.js -a hello -b world
>>>命令行中
hello //为xx.bat文件去掉后缀的文件名
<<<输出
[ 'C:\\Program Files\\nodejs\\node.exe',
'E:\\w\\p1.js',
'-a',
'hello',
'-b',
'world' ]
```
#### 占位符
在上面的栗子中有一个问题,我们所传入的参数是固定的,要想它不固定,需要在.bat文件中使用占位符取代原本固定的参数,再在执行批处理文件时通过传参进行映射。
```
//hello.bat文件中
node p.js %1 %2 %3 %4
>>>命令行中输入
hello -a hello -b world //为xx.bat文件去掉后缀的文件名
<<<输出
[ 'C:\\Program Files\\nodejs\\node.exe',
'E:\\w\\p1.js',
'-a',
'hello',
'-b',
'world' ]
```
[warning] **注意:**
- 此时%后面的数字代表了`%x`这个占位符代表是第几个传入的参数
- %x是从%1开始的而不是%0
上面虽然使传参所传入的参数值不再固定化了,但个数仍然是固定的,so我们推荐下面这种类linux的批处理文件。
### 类linx中的批处理文件
此时,我们不再需要`.bat`后缀名,我们的批处理文件名直接就是`xxx`(不再需要后缀)。
#### 给文件添加可执行权限
假若我们要执行的文件名为hello,要执行这个批处理文件,我们需要先给它添加可执行权限
```
$ chmod +x hello
```
#### 告诉命令行让谁来执行这个文件里的内容
接着,在这个文件中添加一句话,意思是让node来执行这个命令
```
#! /usr/bin/env node
```
#### './'执行文件
最后,如何执行这个文件呢,只需要访问它即可
```
>>>输入
$ ./hello --a -b c
<<< 输出
[ 'C:\\Program Files\\nodejs\\node.exe',
'E:\\w\\hello',
'--a',
'-b',
'c' ]
```
[danger] **注意:** 此时`./`是必须的
#### npm link
如果我们想在输入命令时不需要输入前面的'./',我们就需要用到`npm link`了。
首先,在package.json下,添加这么一段
```
"bin":{
"hello":"hello" //前者为我们输入的命令,后者为要执行的文件的路径(包括文件名)
}
```
接着在package.json所处目录下的命令行中输入
```
npm link
```
这样我们就无需在输入命令时候还要加上`./`前缀,
[important]**注意:**
1. 这是因为npm link后,命令行中的命令指向了npm目录bat文件(npm-link后会自动在npm目录下生成,其作用是将package.json中我们所配置的那个可执行文件挂到这个.bat下),而 bat文件又指向了当前目录 (package.json所处目录)的hello文件(路径)。
2. npm link必须配合#! /usr/bin/env node,否则windows会报脚本执行错误
## yargs
yargs能帮助我们在被执行的文件里所接受的参数进行包装处理。
**yargs.argv就是包装后的process.argv**,除此之外我们还能通过yargs.options对这个包装对象再进行进一步的订制。
[important] **注意:**
和process.argv很大的不同是它返回的是一个对象而不是数组,以**连词线** `-` 或`--`开头的参数会作为对象中的一个key值,而它后面的非连词线开头的参数会作为key的值,如果后面没有非连词线开头的参数则会返回`true`
```
//hello文件中
#! /usr/bin/env node
let yargs = require('yargs');
let argv = yargs.argv; //.argv是必须的
console.log(argv);
>>>命令行中输入
$ ./hello --a 1 -b 2 c
<<<输出
{ _: [ 'c' ],
help: false,
version: false,
a: 1,
b: 2,
'$0': 'hello',}
console.log(argv.a);
<<<输出
1
```
### 下划线属性
我们可以通过访问`argv._`来获取非连词线开头的参数
```
>>>命令行中输入
$ ./hello d --a 1 -b 2 c
<<<输出
[ 'd', 'c' ]
```
### 命令行参数的配置
多个不同参数的配置通过`.option`隔开
```
#! /usr/bin/env node
let yargs = require('yargs');
// let argv = yargs.argv;
let argv = yargs.options('a',{
alias:'ant'
,demand:true
,default:'super'
,describe:'一只灰常大的蚂蚁'
,boolean:false
,type:'string'
}).options('b',{
alias:'BB'
,describe:'woshi bb'
,boolean:false
}).argv;
console.log(argv._);
console.log(argv);
>>>命令行中输入
$ ./p1.js -a valueA -b valueB -c
<<<输出
[]
{ _: [],
help: false,
version: false,
a: 'valueA',
ant: 'valueA',
b: 'valueB',
BB: 'valueB',
c: true,
'$0': 'p1.js' }
```
配置项说明:
- alias:别名,当传入a时也会同时生成ant
- demand:该参数是否必须
- default:默认值
- describe:参数描述
- boolean:设置为true时,若该参数没有传入则会将该参数的值设置为false
![](https://box.kancloud.cn/5ecdb74da71b95725b04ea18579be16f_293x227.png)
- type:限制传入参数的类型
### 配置帮助信息
首先yargs已经默认为我们提供了`--help`参数来显示帮助信息,我们同样的,可以给这个--help参数配置个别名来简化
```
let argv = yargs.此处省略一万字.help('h').argv
>>>命令行中输入
$ ./p1.js --h
<<<输出
选项:
--version 显示版本号 [布尔]
-a, --ant 一只灰常大的蚂蚁 [字符串] [必需] [默认值: "super"]
-b, --BB woshi bb [布尔]
-h 显示帮助信息 [布尔]
```
配置其它的帮助提示
- usage:用法格式
- example:一个详细的使用栗子
- epilog:结尾处的显示,常用来显示命令工具的版本行
```
// hello文件中
...
.help('h')
.usage('hello -[option] value')
.example('我,栗子,让你明白!')
.epilog('copyright 2018-')
.argv;
>>>
$ ./hello -h
<<<
hello -[option] value
选项:
--version 显示版本号 [布尔]
-a, --ant 一只灰常大的蚂蚁 [字符串] [必需] [默认值: "super"]
-b, --BB woshi bb [布尔]
-h 显示帮助信息 [布尔]
示例:
我,栗子,让你明白!
copyright 2018-
```
### yargs实现思路
```
let args = process.argv;
let argv = {};
for(let i=2;i<args.length;++i){
let cur = args[i];
if(/^(--)/.test(cur)){
argv[cur.slice(2)] = args[++i];
}
}
```