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]注意:
这是因为 npm link 后, 命令行中的命令指向了 npm 目录 bat 文件 (npm-link 后会自动在 npm 目录下生成, 其作用是将 package.json 中我们所配置的那个可执行文件挂到这个. bat 下), 而 bat 文件又指向了当前目录 (package.json 所处目录) 的 hello 文件(路径)
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
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];
- }
- }
来源: https://juejin.im/post/5a976e87f265da4e8c453eec