之前的一篇文章前端如何写一个全局命令行?主要聊了如何写一个全局命令行以及介绍了一个辅助工具——yargs,这篇文章我们来聊聊另外一个命令行工具——commander!
初始化
![e4811562498a6435cf9a1d1932ae380f.png](https://i-blog.csdnimg.cn/blog_migrate/0051207d77492115121823c690a801cb.jpeg)
图1
首先要引入commander,parse方法用来解析命令行中传入的参数,和yargs类似,中间加入一个显示版本号的功能,我们运行一下:
![79d10d37b2d737756938c9ee5c113ccb.png](https://i-blog.csdnimg.cn/blog_migrate/8778d02b365c4f1f05e6c863694428a7.jpeg)
图2
图2中打印的版本号符合预期,很好,下面我们可以继续向代码中添加其他逻辑!
选项option
使用格式如下:
.option('-n, --name [p2]', '描述', '默认值')
- n和name分别是短长定义(可以认为n是name的简写);
- p代表选项后面跟着的参数,< >必填,[ ]选填;
- 最后两个参数分别是描述文案和选项的默认值;
![7b708c8f985988bdfce642f6034be457.png](https://i-blog.csdnimg.cn/blog_migrate/44b4dc75575e0ea819f31b23e86de772.jpeg)
图3
如图3所示,添加了一个debug选项,运行结果如下:
![00fb2feea272e4b82b755971cc3452df.png](https://i-blog.csdnimg.cn/blog_migrate/250af648bbc05c4f6aab9ae3eb5cb103.jpeg)
图4
如上图,无论是加-d还是--debug选项,结果都会打印true,如果不加选项就会打印undefined。下面我们就加一下默认值,看看会发生什么?
![c2e2ca17a393b2a83e15973b6a433f77.png](https://i-blog.csdnimg.cn/blog_migrate/f01608b80bedd9d19890b125ffcdb274.jpeg)
图5
我们再运行一下,结果如下:
![6730a6b4a9f39e4499b8dcc0f7600ebb.png](https://i-blog.csdnimg.cn/blog_migrate/fab1fa07f9a00b5b37f60b5df803d5f5.jpeg)
图6
如上图,你会发现加了默认值之后,打印出来的不再是布尔值,而是用户添加的默认值,但是不加选项打印出来的依然是underfined!
我们再把参数放在选项之后看看是什么效果?
![66268b00cd8ecb2d2d9a659aef633044.png](https://i-blog.csdnimg.cn/blog_migrate/f61d3f25b36ec6721301b463803e17b9.jpeg)
图7
运行一下:
![20e0d3942aa47c94f83b112d526a5134.png](https://i-blog.csdnimg.cn/blog_migrate/971fe6dffd204300224bc85d19219adc.jpeg)
图8
如图8所示,你会发现添加了可选参数之后,如果运行时不加选项也依然能够打印出默认值。下面我们换成必填参数看看是什么效果?
![96eddadae047760eb372c6a9c12d8b0e.png](https://i-blog.csdnimg.cn/blog_migrate/862c035faf4010c4325835abd487cccb.jpeg)
图9
如图9所示,不加选项输出没有任何问题,加了选项没有跟参数就会报错,报错的message也很明确,就是告诉你缺少参数,那么-d后面再跟一个参数就没问题了!
option可以链式添加多个,如下:
![e8f12c74f4f67585888e557aca094551.png](https://i-blog.csdnimg.cn/blog_migrate/c3f03f77eafd0802941891751cb17233.jpeg)
图10
用 -nd 运行命令等价于 -n -d,如下:
![a6e015810e1e08aa0d0a8cc1d6742fab.png](https://i-blog.csdnimg.cn/blog_migrate/8fc3d4d10655cd25f68f414f61f477d7.jpeg)
图11
如果在选项前面加上 no- ,含义正好与之前相反,效果如下:
![f1784ab0d1eb76be36c381df07671246.png](https://i-blog.csdnimg.cn/blog_migrate/ae07f90f2bd0f3156651c836c6111446.jpeg)
图12
运行一下:
![b6725af3c39e5816399e2c7bdc870c9b.png](https://i-blog.csdnimg.cn/blog_migrate/80d16800c15979a59592b42539ee8978.jpeg)
图13
不加-d选项输出了true,加了反而输出了false,在某些场景下还是很有用的!
options的第三个参数还可以是函数(此时第四个值就是默认值),此函数接受两个参数:命令行输入的值和选项默认值,函数处理后的返回结果为最终的解析结果,看下面例子:
![e31f149c24c07ea45b9dcd9d531d32ee.png](https://i-blog.csdnimg.cn/blog_migrate/06ca20b496c0d9b8202497036b38b444.jpeg)
图14
运行一下,结果如下:
![f82e584e318772d30371b5631e92226b.png](https://i-blog.csdnimg.cn/blog_migrate/7f89b9a2584f825f8c5f2a222534221e.jpeg)
图15
如图15所示,如果不加选项返回的是默认值,如果加了选项和参数,那么就会进入函数中经过一番处理返回最终的结果!
命令command第一种用法(Action handler (sub)commands)
使用格式
.command('add [params]').description('描述').alias('简称').action(function(){ }) //命令处理函数
看一个例子:
![219ae91365bf29de270dd728f94fa46f.png](https://i-blog.csdnimg.cn/blog_migrate/85bf5abfa0ee9c1a5e7810179b656e88.jpeg)
图16
和option一样,< >和[ ]分别代表必填和选填,图16中有三个点的写法表示剩余的参数都放在other这个数组里面,类似于es6中的语法。
action处理函数的参数与命令中的参数一一对应,但是最后一个参数有所不同,通过最后一个参数cmdObj可以获取option对应的输入值。
运行一下,如图17所示:
![7ecc9f9b9c812599b8b4ecaaaf7ec9de.png](https://i-blog.csdnimg.cn/blog_migrate/6e462982e594c12944154b5690b246f2.jpeg)
图17
第一种写法比较简单,我想大家一看就会明白!
命令command第二种用法(Git-style executable (sub)commands)
使用格式
.command('add [params]', 'install description', opts)
- 第二个参数是描述
- 第三个参数是命令辅助修饰对象(可选)
- 当 .command() 带有描述参数时,不能采用 .action(callback) 来处理子命令,否则会出错,这告诉 commander,你将采用单独的可执行文件作为子命令。
![ef2d54fd35703228fb20897f530fe290.png](https://i-blog.csdnimg.cn/blog_migrate/3720b61d0a1f7d333d7d1b42659a2959.jpeg)
图18
我们运行一下图18,结果如下:
![2cad3f619d375604f3af056597aa67ef.png](https://i-blog.csdnimg.cn/blog_migrate/50260e662a8fcec1f6f551c364eaad22.jpeg)
图19
报错了,提示我们commder-init不存在,其实是commander在运行目录下寻找名为commder-init的文件没有找到导致的,我们现在添加一个这样的文件:
![21af3fbcf0ec757b77520cba9010c8ff.png](https://i-blog.csdnimg.cn/blog_migrate/1a055b019cd1450d84a4c13f0e9f2bb6.jpeg)
图20
再次运行一下:
![c66c3e180ff3a45c99157213e57b973a.png](https://i-blog.csdnimg.cn/blog_migrate/6e64c0bacd5dc644e8e7fef237bd7334.jpeg)
图21
结果是符合预期的,非常好!
参数arguments
直接看一个例子便会明白:
![d87c28710037d4a7801a6e179656672b.png](https://i-blog.csdnimg.cn/blog_migrate/7f4ee51553b080617b0776d4e4c6e401.jpeg)
图22
运行一下:
![e74f41fac3e24120070f066b93e6de9b.png](https://i-blog.csdnimg.cn/blog_migrate/d84e6f25a64ffab443bc1333cf06320d.jpeg)
图23
如图23所示,不需要加任何命令就能进入action处理函数,如果你写的命令行只有一个命令,那么你可以采取这种方式!
用法帮助文档输出
在命令后面加-h或者--help就会默认输出一段说明,如下:
![fd115a58957b61f1238aef287e6079cd.png](https://i-blog.csdnimg.cn/blog_migrate/ec63d6e10d8162fb177d006b372042be.jpeg)
图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