commander 是node.js命令行接口的完整解决方案。
- 创建命令及配置参数
- 显示使用错误
- 可以提供帮助提示
安装(这里以@11.0.0版本为例)
npm install commander@11.0.0 -S
导入方式
const { program } = require("commander"); // program 是 Command的一个实例
// 或者 两种方式本质上是一样
// const { Command } = require('commander');
// const program = new Command();
version 方法定义要开发的程序的版本号,接收三个参数
- 类型[string]
必填参数,版本号,例:1.0.0 - 类型[string] 可选参数,自定义选项名称,默认
-V(短命令) | --version(长命令), 命令之间可以用逗号、空格、|分割,且短名称和长名称都最多只能有一个 - 类型[string] 可选参数,命令描述
const { program } = require("commander");
program.version("0.1.0", "-v|--version", "版本号");
program.parse(process.argv); // 此行代码控制终端是否展示命令结果
重要方法option,接收以下参数
- 类型[string]
必填参数,自定义选项名称,-f(短命令) |--feer(长命令) , 命令之间可以用逗号、空格、|分割,且短名称和长名称都最多只能有一个 - 类型[string] 可选参数,选项描述
- 类型[((v,prev) => v)|string|boolean|string[]] 可选参数,如果传入的是
函数,则可以通过函数修改返回值,如果不是函数则当默认值处理 - 类型[string|boolean|string[]]
当且仅当 3 是函数时,此参数有意义且是默认值
option 接收4个参数时
- 选项有必填参数时
const { program } = require("commander");
/*option 定义选项
参数1. (-t, --test) (-t|--test) (-t --test) 三种写法都可以,定义选项短(长)命名
参数1. <n> 选项参数,可不定义 (<>是必填,[]是可选,[a...]是多个可选参数)
参数2. “测试” 针对该选项的描述
参数3. (v, prev) => v + "-" + prev 修改返回结果
参数4. "12" 默认值
*/
program
.option("-t, --test <n>", "测试", (v, prev) => v + "-" + prev, "12")
.action((p) => {
console.log("拿到的参数为:", p);
// 输入33, 得到结果 { test: '33-12' }
});
- 选项有可选参数时
const { program } = require("commander");
program.option("-t, --test [m]", "测试", 321).action((v) => {
// 执行 node ./program.js
console.log("得到结果:", v, "默认值:", program.opts().test);
// 得到结果: { test: 321 } 默认值: 321 未传入选项参数,则拿到默认值
/* 执行 node ./program.js -t 00
console.log("得到结果:", v, "默认值:", program.opts().test);
得到结果:{ test: '00' } 默认值: 00 传入00 则会覆盖默认值
*/
});
option 接收3个参数时
const { program } = require("commander");
/*option 定义选项
参数1/2 和上面一样
参数3. "12" 默认值
*/
program.option("-a, --add <n>", "测试", "12").action((p) => {
console.log("拿到的参数为:", p);
// 输入33, 得到结果 { add: '33' }
});
addOption 该方法传入一个Option实例,可以定义一些复杂的选项(option方法不能满足)
1.choices用法,程序会自动检测输入选项是否存在,不存在则报错(程序自动检测选项参数合法性)
const { program, Option } = require("commander");
// 接收一个参数 Option 类
program
.addOption(
new Option("-s, -save <size>", "尺寸").choices(["small", "normal", "large"])
)
.action((v) => {
// 错误示范 node ./addOption.js -s 12 输入的是非"small", "normal", "large"时 报错“error: option '-s, -save <size>' argument '12' is invalid. Allowed choices are small, normal, large.”
// 正确 node ./addOption.js -s large 得到参数 { Save: 'large' }
console.log("得到参数", v);
})
.parse();
2.默认值用法,设置默认值时如果要得到默认值,执行命令时均不带选项名称
const { program, Option } = require("commander");
// 接收一个参数 Option 类
program
.addOption(
new Option("-s, --save [size]", "尺寸") // 选项参数改为了可选
.choices(["small", "normal", "large"])
.default("small") // 默认值设置
)
.action((v) => {
// node ./addOption.js 不带选项名称时 得到参数 { save: 'small' }{ save: 'small' }
console.log("得到参数", v, program.opts());
})
.parse();
3.其他用法
program
.addOption(new Option("-s, --secret").hideHelp()) // 帮助提示隐藏该选项
.addOption(
new Option("-t, --timeout <delay>", "timeout in seconds").default(
60,
"one minute"
) // 设置默认值
)
.addOption(
new Option("-d, --drink <size>", "drink size").choices([
"small",
"medium",
"large",
]) // 定义选项范围
)
.addOption(new Option("-p, --port <number>", "port number").env("PORT"))
.addOption(
new Option("--donate [amount]", "optional donation in dollars")
.preset("20")
.argParser(parseFloat) // 对输入结果做解析格式化操作
)
.addOption(
new Option("--disable-server", "disables the server").conflicts("port")
// 和选项port 互斥,不能连用如:node ./addOption.js --disable-server -p 30
)
.addOption(
new Option("--free", "small drink included free ").implies({
drink: "12",
}) // 添加额外选项参数值
)
.action((v) => {
console.log(v);
})
.parse();
command 创建命令, 接收两个参数
- 第一个参数和option类似(
命令不需要加-和--) - 第二参数是对象 {hidden:帮助提示时是否隐藏该命令,isDefault:是否是默认命令}
const { program } = require("commander");
/** 创建一个clone命令,该命令用一个必填参数,一个可选参数 */
program
.command("clone <source> [destination]")
.description("clone a repository into a newly created directory")
.action((source, destination) => {
console.log("得到参数", source, destination);
// 执行 node ./command.js clone 12 得到参数 clone 12
})
.parse();
argument 定义参数的方法
- 类型[string] 必填参数,定义可选
[]、必填<> - 类型[string] 可选参数,定义的参数的描述
- 类型[((v,prev) => v)|string|boolean|string[]] 可选参数,如果传入的是函数,则可以通过函数修改返回值,如果不是函数则当默认值处理
- 类型[string|boolean|string[]] 当且仅当 3 是函数时,此参数有意义且是默认值
const { program } = require("commander");
program
.version("0.1.0")
.argument("<username>", "user to login")
.argument("[password]", "password for user, if required", 123456)
.action((username, password) => {
console.log("username:", username);
console.log("password:", password);
// 执行node ./argument.js name, 得到结果 username: name password: 123456
})
.parse();
以上就是一些关键的函数,接下来列举些案例
- 模拟 git clone 命令, 添加选项 -b 未输入时默认是 master
const { program } = require("commander");
program
.command("clone")
.argument("<source>", "远程仓库地址")
.option("-b, --branch", "指定分支", "master")
.action((p, b) => {
console.log("拿到参数:", p, b);
// 执行 node ./demo.js clone https://githup*** -b dev
// 终端打印:拿到参数: https://githup*** { branch: true }
});
program.parse();
- 模拟 npm 安装依赖命令
const { program } = require("commander");
program
.command("i")
.description("安装依赖")
.argument("<name>", "依赖名称")
.option("-dev, --devloop", "安装到开发依赖")
.option("-prod, --production", "安装到生产依赖")
.action((p1, p2) => {
console.log("得到参数", { p1, p2 });
// 执行 node ./demo.js i dayjs -dev
// 终端打印:得到参数 { p1: 'dayjs', p2: { devloop: true } }
});
program
.command("install")
.description("安装依赖")
.argument("<name>", "依赖名称")
.option("-dev, --devloop", "安装到开发依赖")
.option("-prod, --production", "安装到生产依赖")
.action((p1, p2) => {
console.log("得到参数", { p1, p2 });
// 执行 node ./demo.js install dayjs -dev
// 终端打印:得到参数 { p1: 'dayjs', p2: { devloop: true } }
});
program.parse();
以上就是本节主要内容,由于技术有限,见解较浅,希望各路大神多多指导
以上案例代码如有需要,可克隆本地运行
git clone https://gitee.com/luocheng-fu/commander-demo.git