UDN-企业互联网技术人气社区

板块导航

浏览  : 384
回复  : 3

[Nodejs] nodejs命令行应用程序管理模块commander

[复制链接]
cat77的头像 楼主
发表于 2017-1-3 14:56:26 | 显示全部楼层 |阅读模式
  在这篇文章的demo文章中,我是这样管理命令行参数的:
  1. var cmd=process.argv[2];
  2. if(cmd){
  3.     switch(cmd){
  4.         case "name":
  5.             console.log("邹成卓");
  6.             break;
  7.         case "site":
  8.             console.log("http://zoucz.com");
  9.             break;
  10.         case "email":
  11.             console.log("405966530@qq.com");
  12.             break;
  13.     }
  14. }
  15. ```
复制代码

  当我们使用例如这样`node test01.js -b -p -P -c czzou`的命令来运行nodejs程序,在程序中可以通过`process.argv`来获取请求参数,打印出这些参数,可以看到:
  1. `console.log(process.argv);`
  2. ```json
  3. [ 'C:\\Program Files\\nodejs\\node.exe',
  4.   'D:\\learn\\nodejsLearn\\commanderLearn\\test01.js',
  5.   '-b',
  6.   '-p',
  7.   '-P',
  8.   '-c',
  9.   'czzou' ]
复制代码

  我们在命令行程序中需要解析这些命令来设置一些属性,执行一些操作,或者输出命令帮助信息等,每次自己去写一堆代码处理这些逻辑,每个人的方法还各自不同,是不是显得有点too young too native啊!

  实际上nodejs社区里边已经有了比较成熟的命令行管理工具,例如我今天学的这一款: https://github.com/tj/commander.js ,下面跟着官方示例来学习一下这个模块的用法。

  命令解析、参数解析

  可以看看下面这个demo
  1. #!/usr/bin/env node

  2. var program = require('commander');

  3. program
  4.   .version('0.0.1')
  5.   .option('-p, --peppers', 'Add peppers')
  6.   .option('-P, --pineapple', 'Add pineapple')
  7.   .option('-b, --bbq-sauce', 'Add bbq sauce')
  8.   .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
  9.   .parse(process.argv);

  10. console.log('you ordered a pizza with:');
  11. if (program.peppers) console.log(' - peppers');
  12. if (program.pineapple) console.log(' - pineapple');
  13. if (program.bbqSauce) console.log(' - bbq');
  14. console.log(' - %s cheese', program.cheese);
复制代码

  .version函数,设置版本号

  接收一个字符串作为版本号,运行 node test01.js --version/-V 命令时,会在控制台中输出此版本号。

  .option函数,接收命令设置属性

  接收三个参数:接收命令,多个命令以逗号分隔、命令描述、命令参数默认值。

  -c, --cheese [type] 中括号括起来的属性代表此命令可以接收参数,如果命令不能接收参数,则受到此命令时,命令属性为true,否则为false,如果命令可以接收参数,则命令属性值为命令中输入的值。

  这里注意: 尖括号代表必须输入的命令参数,中括号代表可选的命令参数

  .parse函数

  .parse(process.argv) 传入process.argv给commander模块以解析。

  上面的demo以命令 node test01.js -b -p -P -c czzou 运行的结果:
  1. - you ordered a pizza with:
  2. - peppers
  3. - pineapple
  4. - bbq
  5. - czzou cheese
复制代码

  option函数命令参数Parse函数

  commander允许用户自行限制命令输入的参数类型,option函数的第三个参数可以用来传入一个函数来处理用户输入的命令,用法如下:
  1. functionrange(val){
  2.   return val.split('..').map(Number);
  3. }

  4. functionlist(val){
  5.   return val.split(',');
  6. }

  7. functioncollect(val, memo){
  8.   memo.push(val);
  9.   return memo;
  10. }

  11. functionincreaseVerbosity(v, total){
  12.   return total + 1;
  13. }

  14. program
  15.   .version('0.0.1')
  16.   .usage('[options] <file ...>')
  17.   .option('-i, --integer <n>', 'An integer argument', parseInt)
  18.   .option('-f, --float <n>', 'A float argument', parseFloat)
  19.   .option('-r, --range <a>..<b>', 'A range', range)
  20.   .option('-l, --list <items>', 'A list', list)
  21.   .option('-o, --optional [value]', 'An optional value')
  22.   .option('-c, --collect [value]', 'A repeatable value', collect, [])
  23.   .option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0)
  24.   .parse(process.argv);

  25. console.log(' int: %j', program.integer);
  26. console.log(' float: %j', program.float);
  27. console.log(' optional: %j', program.optional);
  28. program.range = program.range || [];
  29. console.log(' range: %j..%j', program.range[0], program.range[1]);
  30. console.log(' list: %j', program.list);
  31. console.log(' collect: %j', program.collect);
  32. console.log(' verbosity: %j', program.verbose);
  33. console.log(' args: %j', program.args);
复制代码

  通过正则表达式限定命令参数

  除了传入函数来Parse参数,option函数还支持用正则表达式限定参数:
  1. program
  2.   .version('0.0.1')
  3.   .option('-s --size <size>', 'Pizza size', /^(large|medium|small)$/i, 'medium')
  4.   .option('-d --drink [drink]', 'Drink', /^(coke|pepsi|izze)$/i)
  5.   .parse(process.argv);

  6. console.log(' size: %j', program.size);
  7. console.log(' drink: %j', program.drink);
复制代码

  命令执行

  命令执行函数

  通过command函数和action函数配合,可以做命令执行的功能:
  1. #!/usr/bin/env node

  2. var program = require('commander');
  3. program
  4.   .version('0.0.1')
  5.   .command('rmdir')
  6.   .action(function(){
  7.     console.log('rmdir');
  8.   });
  9. program.parse(process.argv);
复制代码

  这种方式即可定义一个rmdir命令,用户输入此命令之后执行传入.action函数的回调函数

  命令执行函数参数
  1. #!/usr/bin/env node

  2. var program = require('commander');

  3. program
  4.   .version('0.0.1')
  5.   .command('rmdir <dir> [otherDirs...]')
  6.   .action(function(dir, otherDirs){
  7.     console.log('rmdir %s', dir);
  8.     if (otherDirs) {
  9.       otherDirs.forEach(function(oDir){
  10.         console.log('rmdir %s', oDir);
  11.       });
  12.     }
  13.   });

  14. program.parse(process.argv);
复制代码

  同上一节命令解析中的参数解析一样,执行命令时也可以传入参数,后边的 [otherDirs...] 表示一个可变参数,可以接收任意多个用户传入的参数。

  输入命令: node test02.js rmdir aaa bbb ccc ,得到结果:
  1. - rmdir aaa
  2. - rmdir bbb
  3. - rmdir ccc
复制代码

  子命令文件执行
  1. #!/usr/bin/env node

  2. var program = require('commander');

  3. program
  4.     .version('0.0.1')
  5.     .command('install [name]', 'install one or more packages', {isDefault: true})
  6.     .command('search [query]', 'search with optional query')
  7.     .command('list', 'list packages installed')
  8.     .parse(process.argv);
复制代码

  这种情况,需要执行命令,还带有命令说明语句的,commander是不支持直接写上回调的!这里我觉得很奇怪,不知道为啥要这样设计。。。

  官方推荐的做法是,在另一个文件中定义子命令:

  例如,刚刚的文件名为 pm.js ,则在同级目录可新建一个文件 pm-install.js ,用来执行install命令,其写法及参数接收方法为:
  1. #!/usr/bin/env node

  2. var program = require('commander');

  3. program
  4.     .option('-f, --force', 'force installation')
  5.     .parse(process.argv);

  6. var pkgs = program.args;

  7. if (!pkgs.length) {
  8.     console.error('packages required');
  9.     process.exit(1);
  10. }

  11. console.log();
  12. if (program.force) console.log(' force: install');
  13. pkgs.forEach(function(pkg){
  14.     console.log(' install : %s', pkg);
  15. });
  16. console.log();
复制代码

  设定命令格式,接收满足格式的命令
  1. #!/usr/bin/env node

  2. var program = require('../');

  3. program
  4.   .version('0.0.1')
  5.   .arguments('<cmd> [env]')
  6.   .action(function(cmd, env){
  7.      cmdValue = cmd;
  8.      envValue = env;
  9.   });

  10. program.parse(process.argv);

  11. if (typeof cmdValue === 'undefined') {
  12.    console.error('no command given!');
  13.    process.exit(1);
  14. }
  15. console.log('command:', cmdValue);
  16. console.log('environment:', envValue || "no environment given");
复制代码

  启用–harmony模式
1.png

  在低版本的nodejs上,若想启用es6的部分新特性,可以使用–harmony模式。 启用–harmony有两种方法:

  • 文件首行加上 #! /usr/bin/env node --harmony
  • 使用这样的命令启动node程序 node --harmony examples/pm publish

  输出帮助信息

  commander提供了自动输出帮助信息的能力:

  xxx -h 或者 xxx --help :
1.png

  有此利器,用nodejs开发命令行程序那是简单又顺手啊 :)

相关帖子

发表于 2017-1-3 14:56:56 | 显示全部楼层
JavaScript依赖于浏览器本身,与操作环境无关,只要计算机能运行浏览器,并支持JavaScript的浏览器,就可正确执行,从而实现了“编写一次,走遍天下”的梦想。
使用道具 举报

回复

发表于 2017-1-3 14:56:57 | 显示全部楼层
貌似看过类似的文章恩,排版更清晰点就更好了
使用道具 举报

回复

发表于 2017-1-3 14:56:58 | 显示全部楼层
前排支持下
使用道具 举报

回复

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关于我们
联系我们
  • 电话:010-86393388
  • 邮件:udn@yonyou.com
  • 地址:北京市海淀区北清路68号
移动客户端下载
关注我们
  • 微信公众号:yonyouudn
  • 扫描右侧二维码关注我们
  • 专注企业互联网的技术社区
版权所有:用友网络科技股份有限公司82041 京ICP备05007539号-11 京公网网备安1101080209224 Powered by Discuz!
快速回复 返回列表 返回顶部