之前的一篇文章前端如何写一个全局命令行?主要聊了如何写一个全局命令行以及介绍了一个辅助工具——yargs,这篇文章我们来聊聊另外一个命令行工具——commander!
初始化

图1
首先要引入commander,parse方法用来解析命令行中传入的参数,和yargs类似,中间加入一个显示版本号的功能,我们运行一下:

图2
图2中打印的版本号符合预期,很好,下面我们可以继续向代码中添加其他逻辑!
选项option
使用格式如下:
.option('-n, --name [p2]', '描述', '默认值')
- n和name分别是短长定义(可以认为n是name的简写);
- p代表选项后面跟着的参数,< >必填,[ ]选填;
- 最后两个参数分别是描述文案和选项的默认值;

图3
如图3所示,添加了一个debug选项,运行结果如下:

图4
如上图,无论是加-d还是--debug选项,结果都会打印true,如果不加选项就会打印undefined。下面我们就加一下默认值,看看会发生什么?

图5
我们再运行一下,结果如下:

图6
如上图,你会发现加了默认值之后,打印出来的不再是布尔值,而是用户添加的默认值,但是不加选项打印出来的依然是underfined!
我们再把参数放在选项之后看看是什么效果?

图7
运行一下:

图8
如图8所示,你会发现添加了可选参数之后,如果运行时不加选项也依然能够打印出默认值。下面我们换成必填参数看看是什么效果?

图9
如图9所示,不加选项输出没有任何问题,加了选项没有跟参数就会报错,报错的message也很明确,就是告诉你缺少参数,那么-d后面再跟一个参数就没问题了!
option可以链式添加多个,如下:

图10
用 -nd 运行命令等价于 -n -d,如下:

图11
如果在选项前面加上 no- ,含义正好与之前相反,效果如下:

图12
运行一下:

图13
不加-d选项输出了true,加了反而输出了false,在某些场景下还是很有用的!
options的第三个参数还可以是函数(此时第四个值就是默认值),此函数接受两个参数:命令行输入的值和选项默认值,函数处理后的返回结果为最终的解析结果,看下面例子:

图14
运行一下,结果如下:

图15
如图15所示,如果不加选项返回的是默认值,如果加了选项和参数,那么就会进入函数中经过一番处理返回最终的结果!
命令command第一种用法(Action handler (sub)commands)
使用格式
.command('add [params]').description('描述').alias('简称').action(function(){ }) //命令处理函数
看一个例子:

图16
和option一样,< >和[ ]分别代表必填和选填,图16中有三个点的写法表示剩余的参数都放在other这个数组里面,类似于es6中的语法。
action处理函数的参数与命令中的参数一一对应,但是最后一个参数有所不同,通过最后一个参数cmdObj可以获取option对应的输入值。
运行一下,如图17所示:

图17
第一种写法比较简单,我想大家一看就会明白!
命令command第二种用法(Git-style executable (sub)commands)
使用格式
.command('add [params]', 'install description', opts)
- 第二个参数是描述
- 第三个参数是命令辅助修饰对象(可选)
- 当 .command() 带有描述参数时,不能采用 .action(callback) 来处理子命令,否则会出错,这告诉 commander,你将采用单独的可执行文件作为子命令。

图18
我们运行一下图18,结果如下:

图19
报错了,提示我们commder-init不存在,其实是commander在运行目录下寻找名为commder-init的文件没有找到导致的,我们现在添加一个这样的文件:

图20
再次运行一下:

图21
结果是符合预期的,非常好!
参数arguments
直接看一个例子便会明白:

图22
运行一下:

图23
如图23所示,不需要加任何命令就能进入action处理函数,如果你写的命令行只有一个命令,那么你可以采取这种方式!
用法帮助文档输出
在命令后面加-h或者--help就会默认输出一段说明,如下:

图24
如果觉得用法说明不够详细,可以监听--help事件,如下:
program.on('--help', function() { console.log('这里写你的用法说明文档');});
再运行上面的命令就会执行--help的回调内容
如果想修改图24中红色区域的内容可以使用下面的格式:
program .name("命令名称") //commder .usage("选项参数顺序说明") // [options] [command]
总结
这篇文章主要介绍了commander的用法,帮助大家可以更好的写一个全局命令行。另外如果大家自己去看文档的话,要注意文档中的一些方法和参数已经不存在了,可能是版本更新了但是README还没来得及更新造成的!个人感觉它和yargs的很多功能都很类似,其实它两在npm托管平台上周下载量差不多,大家根据自己的口味自行选择吧!
使用示例
#!/usr/bin/env node
const program = require('commander');
const { version } = require('../package.json');
program.version(version, '-v, --version', 'display current version');
// 运行本地服务
program
.command('serve')
.description('run location server')
.option('-t, --template <template>', 'choice project template', 'VUE2')
.action((name, cmd) => {
require('../commands/serve')(name, cmd);
});
// 执行项目打包
program
.command('build')
.description('build dist')
.option('-t, --template <template>', 'choice project template', 'VUE2')
.option('-m, --mode <mode>', 'choice build mode', 'prd')
.option('-r, --report', 'show bundle analysis')
.action((name, cmd) => {
require('../commands/build')(name, cmd);
});
// 输出配置参数
program
.command('inspect')
.description('inspect webpack config')
.option('-m, --mode <mode>', 'choice build mode', 'prd')
.action((name, cmd) => {
require('../commands/inspect')(name, cmd);
});
// 代码提交前 代码格式校验
program
.command('precommit')
.description('check code style before git commit')
.action((name, cmd) => {
require('../commands/precommit')(name, cmd);
});
// 代码提交时 提交消息校验
program
.command('commitmsg')
.description('check message style before git commit')
.action((name, cmd) => {
require('../commands/commitmsg')(name, cmd);
});
// eslint自动修复
program
.command('lintfix')
.description('fix all of eslint‘errors which can be solved automatically')
.action((name, cmd) => {
require('../commands/lintfix')(name, cmd);
});
// 可视化界面
program
.command('ui')
.description('start and open the hlcli ui')
.action((name, cmd) => {
require('../commands/ui')(name, cmd);
});
program.parse(process.argv);
转载于:https://blog.csdn.net/weixin_39682897/article/details/110304020