Commander.js node.js命令行界面的完整解決方案,受 Ruby Commander啓發。
前端開發node cli 必備技能。
Install
$ npm install commander
API
version
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
- 使用
.option()
方法定義commander
的選項options
, - 示例:
.option('-n, --name <items1> [items2]', 'name description', 'default value')
- 參數解析:
- 自定義標誌<必須>:分爲長短標識,中間用逗號、豎線或者空格分割;標誌後面可跟必須參數或可選參數,前者用
<>
包含,後者用[]
包含 - 選項描述<省略不報錯>:在使用 --help 命令時顯示標誌描述
- 默認值<可省略>
- 短標誌可以作爲單獨的參數傳遞。像 -abc 等於 -a -b -c。多詞組成的選項,像“--template-engine”會變成 program.templateEngine 等。
command
- 作用:添加命令名稱,
- 示例:`.command('add <num>
[otherDirs...]', 'install description', opts)`
- 參數解析:
- 命令名稱<必須>:命令後面可跟用 <> 或 [] 包含的參數;命令的最後一個參數可以是可變的,像實例中那樣在數組後面加入 ... 標誌;在命令後面傳入的參數會被傳入到 action 的回調函數以及 program.args 數組中
- 命令描述<可省略>:如果存在,且沒有顯示調用action(fn),就會啓動子命令程序,否則會報錯
- 配置選項<可省略>:可配置noHelp、isDefault等
alias description usage
定義命令的別名 描述和用法
.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
定義命令的回調函數 用法示例:.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
Eg:
自定義校驗
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
Variadic arguments可變參數
命令command有且只有最後一個參數可變不固定的。 要使參數變量可變,必須將...附加到參數名稱。
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的參數獲取。
指定參數語法 Specify the argument syntax
#!/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
Git風格的子命令
當 .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
.outputHelp(cb)
輸出幫助信息而不退出。 回調cb允許在顯示幫助文本之前對其進行後處理。如果要在默認情況下顯示幫助(例如,如果未提供command),則可以使用以下內容:
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
}
help(cb)
自定義事件監聽,回調cb允許在顯示幫助文本之前對其進行後處理。
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