例如vue-cli:vue
其中解析參數使用的都是commander模塊,要看懂工具幹了啥,理解commander就格外重要了!node
當一個Nodejs程序運行時,process
對象中有一個叫作argv
的屬性。命令行程序的第一個重頭戲就是解析這個process.argv
屬性。
git
定義一個hello腳本,打印一下process.argvgithub
#!/usr/bin/env node
console.log('hello ', process.argv);複製代碼
在終端輸入$ hello a b c
看起來process.argv
好像是一個數組,其中第一個元素是node的執行路徑,第二個元素是當前執行文件的路徑,從第三個元素開始,是執行時帶入的參數。
web
固然能夠本身解析argv參數正則表達式
commander.js是TJ所寫的一個工具包,其做用是讓node命令行程序的製做更加簡單。vue-cli
安裝很簡單,npm
$ npm install commander複製代碼
// file: ./bisheng
#!/usr/bin/env nodeconst program = require('commander');const package = require('../package.json');program .version(package.version) .option('-f, --foo', 'enable some foo') .option('-b, --bar', 'enable some bar') .option('-B, --baz', 'enable some baz');program.on('--help', function(){ console.log(''); console.log('Examples:'); console.log(' $ custom-help --help'); console.log(' $ custom-help -h');});program.parse(process.argv);複製代碼
命令來執行它$ ./bisheng -h複製代碼
commander.js第一個優點就是提供了簡介的api對可選項、參數進行解析。第二個優點就是自動生成幫助的文本信息。
json
做用:用於定義命令選項:.option('-n, --name <name>', 'your name', 'GK')
api
做用:添加命令名稱 用法示例:.command('rmdir [otherDirs...]', 'install description', opts)
參數解析:
Command
對象,如有第二個參數,將返回原型對象。action(fn)
時,則將會使用子命令模式。./pm
,./pm-install
,./pm-search
等。這些子命令跟主命令在不一樣的文件中。 做用:自定義別名 用法 .alias('ex')
做用:定義命令的描述 用法示例:.description('rmdir desc')
用法:.action(fn)
用於設置命令執行的相關回調。fn
能夠接受命令的參數爲函數形參,順序與command()
中定義的順序一致。
用法:program.parse(process.argv)
此api通常是最後調用,用於解析process.argv
。
用法:program.outputHelp()
通常用於未錄入參數時自動打印幫助信息
.option()
方法用來定義帶選項的 commander,同時也做爲這些選項的文檔。下面的例子會解析來自 process.argv
指定的參數和選項,沒有匹配任何選項的參數將會放到 program.args
數組中。
#!/usr/bin/env node
var program = require('commander');
program
.version('0.0.1')
.option('-p, --peppers', 'Add peppers')
.option('-P, --pineapple', 'Add pineapple')
.option('-b, --bbq-sauce', 'Add bbq sauce')
.option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
.parse(process.argv);
console.log('you ordered a pizza with:');
if (program.peppers) console.log(' - peppers');
if (program.pineapple) console.log(' - pineapple');
if (program.bbqSauce) console.log(' - bbq');
console.log(' - %s cheese', program.cheese);複製代碼
執行命令$ ./bisheng -p 或者 ./bisheng --peppers
program.peppers的值爲true複製代碼
執行命令$ ./bisheng -c 123
program.cheese值爲123 默認值爲marble複製代碼
#!/usr/bin/env node
var program = require('commander');
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.0.1')
.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);複製代碼
program
.version('0.0.1')
.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);複製代碼
一個命令的最後一個參數能夠是可變參數, 而且只有最後一個參數可變。爲了使參數可變,你須要在參數名後面追加 ...
。 下面是個示例:
#!/usr/bin/env node
var program = require('commander');
program
.version('0.0.1')
.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);複製代碼
rmdir <dir> [otherDirs...]
dir 接受參數dir otherDirs爲一個數組接受後面全部的參數(可變參數)複製代碼
尖括號(例如 <cmd>
)表明必填輸入,方括號(例如 [env]
)表明可選輸入。
#!/usr/bin/env node
var program = require('commander');
program
.version('0.0.1')
.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");複製代碼
// file: ./bin/bisheng
#!/usr/bin/env nodeconst program = require('commander');const package = require('../package.json');program .version(package.version) .usage('[command] [options]') .command('start [options]', 'to start a server') .command('build [options]', 'to build and write static files to `config.output`') .command('gh-pages [options]', 'to deploy website to gh-pages',{isDefault: true}) .parse(process.argv);複製代碼
當 .command()
帶有描述參數時,不能採用 .action(callback)
來處理子命令,不然會出錯。這告訴 commander,你將採用單獨的可執行文件做爲子命令。 Commander 將會嘗試在入口腳本(例如 ./bin/bisheng
)的目錄中搜索 program-command
形式的可執行文件,例如 bisheng-start
, bisheng-build,bisheng-gh-pages
。
以下:
你能夠在調用 .command()
時傳遞選項。指定 opts.noHelp
爲 true
將從生成的幫助輸出中剔除該選項。指定 opts.isDefault
爲 true
將會在沒有其它子命令指定的狀況下,執行該子命令。
幫助信息是 commander 基於你的程序自動生成的,下面是 --help
生成的幫助信息:
你能夠經過監聽 --help
來控制 -h, --help
顯示任何信息。一旦調用完成, Commander 將自動退出,你的程序的其他部分不會展現。例如在下面的 「stuff」 將不會在執行 --help
時輸出。
#!/usr/bin/env node
var program = require('commander');
program
.version('0.0.1')
.option('-f, --foo', 'enable some foo')
.option('-b, --bar', 'enable some bar')
.option('-B, --baz', 'enable some baz');
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');
複製代碼
不退出輸出幫助信息。 可選的回調可在顯示幫助文本後處理。 若是你想顯示默認的幫助(例如,若是沒有提供命令),你可使用相似的東西:
var program = require('commander');
var colors = require('colors');
program
.version('0.0.1')
.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); // 在控制檯上顯示紅色的幫助文本
}複製代碼