- 查看lerna源码用的就是yargs的库注册脚手架,@vue/cli是自己开发的
- command 命令注册
- options 参数注册
- 常用方法
#!/usr/bin/env node
const yargs = require("yargs/yargs");
const dedent = require("dedent");
// 使用了.parse(argv, context)就不需要传argv了
// const { hideBin } = require("yargs/helpers");
const pkg = require('../package.json');
const cli = yargs()
const ListCmd = require('./command/list')
const context = {
rainbowVersion: pkg.version,
};
const argv = process.argv.slice(2)
// dedent去除缩进
cli
// 未知命令的提示
// .strict()
// $0 值为argv第一个参数
.usage("Usage: $0 <command> [options]")
.demandCommand(
1,
"A command is required. Pass --help to see all available commands and options."
)
// 如果命令输入错误,会提示
.recommendCommands()
.alias("h", "help")
.alias("v", "version")
// 定义多个option参数
.options({
debugger: {
defaultDescription: "",
describe: "bootstrap debugger mode",
type: "boolean",
alias: "d",
},
})
// 注册单个option参数
.option("register", {
describe: "Define Global Option",
type: "string",
alias: "r",
})
.option("ci", {
type: "boolean",
hidden: true,
})
// 定义命令分组
.group(["debugger"], "Dev Options")
.group(["register"], "Extra Options")
// 当输入错误命令的时候的提示内容
.fail((err,msg) => {
/* 此时会把命令中相近的进行提示
是指 init?
无法识别的选项:iii
*/
console.log(err);
})
// 自定义yargs命令,有四个参数
// 可以使用rainbow-test init -h查看帮助文档
.command(
"[init [name]]",
"Do init a project",
(yargs) => {
yargs.option("name", {
type: "string",
describe: "Name of a Project",
alias: "n",
});
},
(argv) => {
console.log(argv); //查看参数
/*
{
_: [ 'init' ],
rainbowVersion: '1.1.0',
'$0': '/usr/local/bin/rainbow-test'
}
*/
}
)
// Lerna源码使用的就是这种方式,但是yargs帮助文档并没有介绍
.command(ListCmd)
.command({
command: "test",
aliases: ["t", "te", "tes"],
describe: "test local packages",
// 在执行脚手架之前完成的东西 ,比如定义私有的options
builder: (yargs) => {
console.log("test the command");
},
// 具体执行逻辑
handler: function handler(argv) {
// return require(".")(argv);
console.log(argv);
return {
initialize() {
console.log("initialize");
},
execute() {
// piping to `wc -l` should not yield 1 when no packages matched
console.log("execute");
},
};
},
})
.command({
command:"start",
alias:['s'],
describe:"start the project",
builder:(yargs)=>{
console.log('');
},
handler:(argv)=>{
console.log(argv);
console.log('start');
setTimeout(()=>{
console.log('setTimeout');
},0);
new Promise(()=>{
let chain = Promise.resolve();
chain.then(() => console.log("chain1"))
chain.then(() => console.log("chain2"))
chain.then(() => console.log("chain3"));
})
let chain = Promise.resolve();
chain.then(() => console.log("chain4"));
setTimeout(()=>{
console.log('setTimeout2');
},0)
console.log("end");
}
})
// 设置输出的宽度
.wrap(cli.terminalWidth())
// 结尾的时候定义内容
.epilogue(
dedent`
When a command fails, all logs are written to lerna-debug.log in the current working directory.
For more information, find our manual at https://github.com/lerna/lerna
`
// 注入参数,比如注册版本号
)
.parse(argv, context);
commander命令注册
#!/usr/bin/env node
const { program } = require("commander");
program.version("0.0.1").parse(process.argv);
默认就由-h
和-V
的命令注册
注册子命令
#!/usr/bin/env node
const { Command } = require("commander");
const pkg = require("../package.json");
// 实例化一个commander实例
const program = new Command();
const options = program.opts();
program
.name(Object.keys(pkg.bin)[0])
.usage(`<command> [options]`)
.version(pkg.version)
.option("-d, --debug", "是否开启调试模式", false) // -d, --debug 是否开启调试模式 (default: false)
.option("-e, --envName <envName>", "获取环境变量")
// command注册命令
const clone = program.command("clone <source> [destination]"); //<>表示必须传入 []为可选
clone
.description("clone a reposity")
.option("-f, --force", "是否开启调试模式", false)
.action((source, destination,Optionsobj) => {
console.log("this is clone command", source, destination);
});
/*
rainbow-test clone 12 14 --force
// this is clone command 12 14 { force: true }
rainbow-test clone --force 12 14
// this is clone command 12 14 { force: true }
rainbow-test clone --force 12 14 --o
// error: unknown option '--o'
不管--force在哪里都可以被识别
*/
/***
* addCommand注册一个service子命令
* rainbow-test service -h
*/
const service = new Command('service')
service
.command("start <port>")
.description("start service at some port")
.action((port) => {
console.log("do service start", port);
});
service
.command("stop")
.description("stop service")
.action(() => {
console.log("stop service");
});
program.addCommand(service); // 完成子命令注册
/**
* 注册rainbow-test-install
*/
program
.command("install [name]", "install package", {
executableFile: "rainbow-cli", //更换执行命令
// isDefault:true, //如果没有输入任何命令,则使用默认命令
hidden:true //隐藏帮助文档中的command
//Error: 'rainbow-install' does not exist
//如果换成已经有的脚手架命令也可以使用
}) //Error: 'rainbow-test-install' does not exist
.alias("i") //install|i [name] install package
/**
* Yargs.demandCommand
* rainbow-test 如果不传入命令, 报错:error: missing required argument 'cmd'
* 如果是未知命令也可以监听到
*/
// program
// .arguments("<cmd> [options]") //Usage下面的命令解释,如果输入未知的命令,怎会提示
// .description("test command", {
// cmd: "command to run",
// options: "options to command",
// })
// .action((cmd, options) => {
// console.log("arguments", cmd, options);
// });
/**
* 高级定制1: 自定义help信息
*/
program.helpInformation = ()=>{ return ''}
program.on("--help", function() {
console.log("youer help infomation\n");
});
// 高级定制:实现debug模式,取代minimist
program.on("option:debug", function() {
if (options.debug) {
process.env.LOG_LEVEL = "verbose";
}
console.log(process.env.LOG_LEVEL);
});
// 高级定制:对未知命令监听
program.on("command:*", function(operands) {
console.error(`error: unknown command '${operands[0]}'`);
const availableCommands = program.commands.map(cmd => cmd.name());
console.log(`可用命令:${availableCommands.join(",")}`);
process.exitCode = 1;
});
// 必须放 在最后面解析参数
program.parse(process.argv);
program.on()
命令监听,自定义输出