1 )概述
2 )快速实现一个 commander 脚手架
npm i commander -S
#!/usr/bin/env node
const pkg = require('../package.json')
const commander = require('commander');
// const { program } = commander; // 脚手架实例 program是一个单例
const program = new commander.Command(); // 这种手动实例化单例,同上,二取一
program
.version(pkg.version) // 设定版本
.parse(process.argv) // 解析所有参数
xyzcli --version
, 并查看结果1.0.0
xyzcli --help
, 并查看结果Usage: xyzcli [options]
Options:
-V, --version output the version number
-h, --help display help for command
3 )commander 通用全局配置
3.1 配置 usage
const program = new commander.Command(); // 这种手动实例化单例,同上,二取一
program
.usage(' [option]' )
.version(pkg.version) // 设定版本
.parse(process.argv) // 解析所有参数
xyzcli -h
, 查看输出Usage: xyzcli <command> [option]
Options:
-V, --version output the version number
-h, --help display help for command
Usage: xyzcli [option]
3.2 配置 name
const program = new commander.Command(); // 这种手动实例化单例,同上,二取一
program
.name(pkg.name)
.usage(' [option]' )
.version(pkg.version) // 设定版本
.parse(process.argv) // 解析所有参数
这里修改下 package.json 中的 name,比如修改成 xyzcli111
执行 $ xyzcli -h
, 查看输出
Usage: xyzcli111 <command> [option]
Options:
-V, --version output the version number
-h, --help display help for command
Usage: xyzcli111 [option]
变成了 xyzcli111在实际应用中,我们会取 bin 属性中的第一个key (一般而言,bin里的配置和包名一致, 但是最好取bin的第一个key值)
const program = new commander.Command();
program
// .name(pkg.name)
.name(Object.keys(pkg.bin)[0]) // 注意这里
.usage(' [option]' )
.version(pkg.version) // 设定版本
.parse(process.argv) // 解析所有参数
这里不做输出测试
3.3 配置 option
const program = new commander.Command(); // 这种手动实例化单例,同上,二取一
program
// .name(pkg.name)
.name(Object.keys(pkg.bin)[0])
.usage(' [option]' )
.version(pkg.version) // 设定版本
.option('-f, --first', '第一个')
.option('-s, --separator ' , '使用分隔符分割', ',')
.option('-d, --debug', '开启调试模式', false)
.option('-e, --envName ' , '获取环境变量名称')
.parse(process.argv) // 解析所有参数
xyzcli -h
, 查看输出Usage: xyzcli <command> [option]
Options:
-V, --version output the version number
-f, --first 第一个
-s, --separator <char> 使用分隔符分割 (default: ",")
-d, --debug 开启调试模式 (default: false)
-e, --envName <envName> 获取环境变量名称
-h, --help display help for command
const program = new commander.Command(); // 这种手动实例化单例,同上,二取一
program
// .name(pkg.name)
.name(Object.keys(pkg.bin)[0])
.usage(' [option]' )
.version(pkg.version) // 设定版本
.option('-f, --first', '第一个') // 选择第一个参数
.option('-s, --separator ' , '使用分隔符分割', ',')
.option('-d, --debug', '开启调试模式', false)
.option('-e, --envName ' , '获取环境变量名称')
.parse(process.argv) // 解析所有参数
const options = program.opts(); // 获取所有可用的 opt 作为参数
const limit = options.first ? 1 : undefined; // 存在第一个参数, 则选1,不存在则不定义
console.log(program.args[0].split(options.separator, limit)); // 基于分隔符分割获取参数
xyzcli -f x,y,z
,查看输出结果[ 'x' ]
xyzcli -s / -f o/p/q
, 查看输出结果[ 'o' ]
4 ) 配置 command 命令
4.1 command
const program = new commander.Command(); // 这种手动实例化单例,同上,二取一
program
// .name(pkg.name)
.name(Object.keys(pkg.bin)[0])
.usage(' [option]' )
.version(pkg.version) // 设定版本
.option('-f, --first', '第一个') // 选择第一个参数
.option('-s, --separator ' , '使用分隔符分割', ',')
.option('-d, --debug', '开启调试模式', false)
.option('-e, --envName ' , '获取环境变量名称')
// 定义一个克隆的命令
const clone = program.command('clone');
clone
.description('克隆仓库')
.action(() => {
console.log('do clone');
});
program.parse(process.argv) // 解析所有参数, 注意这里的调用位置
xyzcli
, 并输出Usage: xyzcli [option]
Options:
-V, --version output the version number
-f, --first 第一个
-s, --separator 使用分隔符分割 (default: ",")
-d, --debug 开启调试模式 (default: false)
-e, --envName 获取环境变量名称
-h, --help display help for command
Commands:
clone 克隆仓库
help [command] display help for command
xyzcli clone -h
, 并输出Usage: xyzcli clone [options]
克隆仓库
Options:
-h, --help display help for command
xyzcli clone
, 并输出do clone
// 定义一个克隆的命令
const clone = program.command('clone );
clone
.description('克隆仓库')
.action((source, destination) => {
console.log('do clone: ', source, destination);
});
program.parse(process.argv) // 解析所有参数, 注意这里的调用位置
xyzcli clone
, 并输出error: missing required argument 'source'
xyzcli clone ss dd
, 并输出do clone: ss dd
// 定义一个克隆的命令
const clone = program.command('clone );
clone
.description('克隆仓库')
.option('--fc, --force', '是否强制克隆', false)
.action((source, destination, cmdObj) => {
console.log('do clone: ', source, destination, cmdObj.force);
});
program.parse(process.argv) // 解析所有参数, 注意这里的调用位置
xyzcli clone ss dd
, 并输出do clone: ss dd false
xyzcli clone ss dd --fc
, 并输出do clone: ss dd true
--
, 不能用一个 -
--fc
同 --force
xyzcli clone --force ss dd
, 并输出do clone: ss dd true
4.2 addCommand
// 定义service脚手架
const service = new commander.Command('service');
service
.command('start [port]')
.description('start service at some port')
.action((port) => {
console.log('service port @', port)
})
program.addCommand(service);
program.parse(process.argv) // 解析所有参数, 注意这里的调用位置
xyzcli -h
, 查看输出Usage: xyzcli [option]
Options:
-V, --version output the version number
-f, --first 第一个
-s, --separator 使用分隔符分割 (default: ",")
-d, --debug 开启调试模式 (default: false)
-e, --envName 获取环境变量名称
-h, --help display help for command
Commands:
clone [options]
xyzcli service -h
, 查看输出Usage: xyzcli service [options] [command]
Options:
-h, --help display help for command
Commands:
start [port] start service at some port
help [command] display help for command
// 定义service脚手架
const service = new commander.Command('service');
service
.command('start [port]')
.description('start service at some port')
.action((port) => {
console.log('service port @', port)
})
service
.command('stop')
.description('stop service')
.action((port) => {
console.log('stop service')
})
program.addCommand(service);
program.parse(process.argv) // 解析所有参数, 注意这里的调用位置
xyzcli service -h
, 查看输出Usage: xyzcli service [options] [command]
Options:
-h, --help display help for command
Commands:
start [port] start service at some port
stop stop service
help [command] display help for command
xyzcli service stop
, 查看输出stop service
4.3 )对命令注册进行自动匹配
// 命令匹配
program
.arguments(' [options]' )
.description('test command')
.action((cmd, options)=> {
console.log(cmd, options);
})
program.parse(process.argv) // 解析所有参数, 注意这里的调用位置
xyzcli test
, 查看输出test undefined
xyzcli
, 查看输出error: missing required argument 'cmd'
xyzcli tt ss
, 查看输出tt ss
xyzcli -h
, 查看输出Usage: xyzcli [option]
test command
Options:
-V, --version output the version number
-f, --first 第一个
-s, --separator 使用分隔符分割 (default: ",")
-d, --debug 开启调试模式 (default: false)
-e, --envName 获取环境变量名称
-h, --help display help for command
Commands:
clone [options]
xyzcli test -h
, 同样也看不到其他实用的信息// 命令匹配
program
.arguments(' [options]' )
.description('test command', {
cmd: 'command to run',
options: 'options for command'
})
.action((cmd, env)=> {
console.log(cmd, env);
})
program.parse(process.argv) // 解析所有参数, 注意这里的调用位置
xyzcli test -h
, 查看输出结果Usage: xyzcli [option]
test command
Arguments:
cmd command to run
options options for command
Options:
-V, --version output the version number
-f, --first 第一个
-s, --separator 使用分隔符分割 (default: ",")
-d, --debug 开启调试模式 (default: false)
-e, --envName 获取环境变量名称
-h, --help display help for command
Commands:
clone [options]
demandCommand
功能类似program
.command('install [name]', 'install package')
program.parse(process.argv) // 解析所有参数, 注意这里的调用位置
xyzcli -h
, 查看输出结果Usage: xyzcli [option]
test command
Arguments:
cmd command to run
options options for command
Options:
-V, --version output the version number
-f, --first 第一个
-s, --separator 使用分隔符分割 (default: ",")
-d, --debug 开启调试模式 (default: false)
-e, --envName 获取环境变量名称
-h, --help display help for command
Commands:
clone [options]
xyzcli install -h
, 查看发现报错
Error: 'xyzcli-install' does not exist
xyzcli-install
npm init install
当输入这个方法的时候也会报错'create-install@latest' is not in the npm registry.
npm init abc
create-abc
这个包program
.command('install [name]', 'install package')
.alias('i')
program.parse(process.argv) // 解析所有参数, 注意这里的调用位置
xyzcli -h
, 查看输出结果Usage: xyzcli [option]
test command
Arguments:
cmd command to run
options options for command
Options:
-V, --version output the version number
-f, --first 第一个
-s, --separator 使用分隔符分割 (default: ",")
-d, --debug 开启调试模式 (default: false)
-e, --envName 获取环境变量名称
-h, --help display help for command
Commands:
clone [options]
program
.command('install [name]', 'install package', {
executableFile: 'npm', // 手动修改可执行文件
})
.alias('i')
program.parse(process.argv) // 解析所有参数, 注意这里的调用位置
xyzcli i i vue -S
program
.command('install [name]', 'install package', {
executableFile: 'npm', // 手动修改可执行文件
isDefault: true, // 默认会匹配这个
// hidden: true, // 不再帮助信息中显示
})
.alias('i')
program.parse(process.argv) // 解析所有参数, 注意这里的调用位置
xyzcli
就直接会匹配到 npm
命令的帮助信息#!/usr/bin/env node
const pkg = require('../package.json')
const commander = require('commander');
// const { program } = commander; // 脚手架实例 program是一个单例
const program = new commander.Command(); // 这种手动实例化单例,同上,二取一
program
// .name(pkg.name)
.name(Object.keys(pkg.bin)[0])
.usage(' [option]' )
.version(pkg.version) // 设定版本
.option('-f, --first', '第一个') // 选择第一个参数
.option('-s, --separator ' , '使用分隔符分割', ',')
.option('-d, --debug', '开启调试模式', false)
.option('-e, --envName ' , '获取环境变量名称')
// 定义一个克隆的命令
const clone = program.command('clone );
clone
.description('克隆仓库')
.option('--fc, --force', '是否强制克隆', false)
.action((source, destination, cmdObj) => {
console.log('do clone: ', source, destination, cmdObj.force);
});
// 定义service脚手架
const service = new commander.Command('service');
service
.command('start [port]')
.description('start service at some port')
.action((port) => {
console.log('service port @', port)
})
service
.command('stop')
.description('stop service')
.action((port) => {
console.log('stop service')
})
program.addCommand(service);
// 设定 install 命令
program
.command('install [name]', 'install package', {
executableFile: 'npm', // 手动修改可执行文件
// isDefault: true,
// hidden: true,
})
.alias('i')
// 命令匹配,用于兜底
program
.arguments(' [options]' )
.description('test command', {
cmd: 'command to run',
options: 'options for command'
})
.action((cmd, env)=> {
console.log(cmd, env);
})
program.parse(process.argv) // 解析所有参数, 注意这里的调用位置