Commander.js node.js命令行界面的完整解決方案,受 Ruby Commander啓發。前端
前端開發node cli 必備技能。node
$ npm install commander
var program = require('commander'); program .version('0.0.1') .parse(process.argv); #執行結果: node index.js -V 0.0.1 #若是但願程序響應-v選項而不是-V選項, #只需使用與option方法相同的語法將自定義標誌傳遞給version方法 program .version('0.0.1', '-v, --version')
.option()
方法定義commander
的選項options
,.option('-n, --name <items1> [items2]', 'name description', 'default value')
<>
包含,後者用 []
包含[otherDirs...]', 'install description', opts)`git
定義命令的別名 描述和用法github
.alias('r') .usage('[options] <file ...>') .description('run setup commands for all envs') #output gp-cli rm --help Usage: rm|r [options] <file ...> run setup commands for all envs Options: -r, --recursive Remove recursively -d --drink [drink] Drink -h, --help output usage information
定義命令的回調函數 用法示例:.action(fn)正則表達式
program .command('rm <dest> [otherDirs...]') .alias('r') .option('-r, --recursive', 'Remove recursively') .option('-d --drink [drink]', 'Drink','Beer') .action(function (d, otherD,cmd) { console.log('remove ' + d ,(cmd.drink ),(cmd.recursive )) if (otherD) { otherD.forEach(function (oDir) { console.log('rmdir %s', oDir); }); } }) #output ✗ gp-cli rm ./aa bb cc -d -r remove ./aa Beer true rmdir bb rmdir cc
function range(val) { return val.split('..').map(Number); } function list(val) { return val.split(','); } function collect(val, memo) { memo.push(val); return memo; } function increaseVerbosity(v, total) { return total + 1; } program .version('0.1.0') .usage('[options] <file ...>') .option('-i, --integer <n>', 'An integer argument', parseInt) .option('-f, --float <n>', 'A float argument', parseFloat) .option('-r, --range <a>..<b>', 'A range', range) .option('-l, --list <items>', 'A list', list) .option('-o, --optional [value]', 'An optional value') .option('-c, --collect [value]', 'A repeatable value', collect, []) .option('-v, --verbose', 'A value that can be increased', increaseVerbosity, 0) .parse(process.argv); console.log(' int: %j', program.integer); console.log(' float: %j', program.float); console.log(' optional: %j', program.optional); program.range = program.range || []; console.log(' range: %j..%j', program.range[0], program.range[1]); console.log(' list: %j', program.list); console.log(' collect: %j', program.collect); console.log(' verbosity: %j', program.verbose); console.log(' args: %j', program.args); # 執行結果 node index.js -i 1.2 -f 1.2 -r 1..2 -l a,b -o hehe -c heihei -v zeze int: 1 float: 1.2 optional: "hehe" range: 1..2 list: ["a","b"] collect: ["heihei"] verbosity: 1 args: ["zeze"]
program .version('0.1.0') .option('-s --size <size>', 'Pizza size', /^(large|medium|small)$/i, 'medium') .option('-d --drink [drink]', 'Drink', /^(coke|pepsi|izze)$/i) .parse(process.argv); console.log(' size: %j', program.size); console.log(' drink: %j', program.drink); # 執行結果 node index.js -s hahah -d hehe size: "medium" drink: true #size 沒有輸入值則報錯,不符合正則則爲默認值,符合正則則爲size #drink 沒有輸入則報undefined,不符合正則則爲true,符合正則則爲drink
命令command有且只有最後一個參數可變不固定的。 要使參數變量可變,必須將...附加到參數名稱。npm
var program = require('commander'); program .version('0.1.0') .command('rmdir <dir> [otherDirs...]') .action(function (dir, otherDirs) { console.log('rmdir %s', dir); if (otherDirs) { otherDirs.forEach(function (oDir) { console.log('rmdir %s', oDir); }); } }); program.parse(process.argv); #執行結果 node index.js rmdir ./hahah aaa bbb ccc rmdir ./hahah rmdir aaa rmdir bbb rmdir ccc # 可變參數的值保存在數組中, 經過program.args以及傳遞action的參數獲取。
#!/usr/bin/env node var program = require('commander'); program .version('0.1.0') .arguments('<cmd> [env]') .action(function (cmd, env) { cmdValue = cmd; envValue = env; }); program.parse(process.argv); if (typeof cmdValue === 'undefined') { console.error('no command given!'); process.exit(1); } console.log('command:', cmdValue); console.log('environment:', envValue || "no environment given"); #執行結果 node arguments.js aaa ccc command: aaa environment: ccc
當 .command() 帶有描述參數時,不能採用 .action(callback) 來處理子命令,不然會出錯。這告訴 commander,你將採用單獨的可執行文件做爲子命令。例如運行gp-cli rm
會搜索同級目錄下面的gp-cli-rm
。數組
#pm 文件內容 program .version('0.0.1') .description('Fake package manager') .command('install [name]', 'install one or more packages').alias('i') .command('search [query]', 'search with optional query').alias('s') .command('list', 'list packages installed') .command('publish', 'publish the package').alias('p') .parse(process.argv); # pm-install 文件內容 #!/usr/bin/env node var program = require('..'); program .option('-f, --force', 'force installation') .parse(process.argv); var pkgs = program.args; if (!pkgs.length) { console.error('packages required'); process.exit(1); } console.log(); if (program.force) console.log(' force: install'); pkgs.forEach(function(pkg){ console.log(' install : %s', pkg); }); console.log(); #output: node ./examples/pm install foo bar baz --force force: install install : foo install : bar install : baz
你能夠經過監聽 --help 來控制 -h, --help 顯示任何信息。一旦調用完成, Commander 將自動退出,你的程序的其他部分不會展現。例如在下面的 「stuff」 將不會在執行 --help 時輸出。函數
var program = require('commander'); program .version('0.1.0') .option('-f, --foo', 'enable some foo') .option('-b, --bar', 'enable some bar') .option('-B, --baz', 'enable some baz'); // must be before .parse() since // node's emit() is immediate program.on('--help', function(){ console.log('') console.log('Examples:'); console.log(' $ custom-help --help'); console.log(' $ custom-help -h'); }); program.parse(process.argv); console.log('stuff'); # output node index.js -h Usage: index [options] Options: -V, --version output the version number -f, --foo enable some foo -b, --bar enable some bar -B, --baz enable some baz -h, --help output usage information Examples: $ custom-help --help $ custom-help -h
輸出幫助信息而不退出。 回調cb容許在顯示幫助文本以前對其進行後處理。若是要在默認狀況下顯示幫助(例如,若是未提供command),則能夠使用如下內容:ui
var program = require('commander'); var colors = require('colors'); program .version('0.1.0') .command('getstream [url]', 'get stream URL') .parse(process.argv); if (!process.argv.slice(2).length) { program.outputHelp(make_red); } function make_red(txt) { return colors.red(txt); //display the help text in red on the console }
自定義事件監聽,回調cb容許在顯示幫助文本以前對其進行後處理。this
program.on('option:verbose', function () { console.log(this.verbose) process.env.VERBOSE = this.verbose; }); // error on unknown commands program.on('command:*', function () { console.error('Invalid command: %s\nSee --help for a list of available commands.', program.args.join(' ')); process.exit(1); }); #alternative // program // .command('*') // .action(function(env){ // console.log('deploying "%s"', env); // }); #output ✗ node ./examples/deploy dd aa Invalid command: dd aa See --help for a list of available commands. ✗ node ./examples/deploy --verbose true