前端脚手架开发利器之一的 Yargs 的学习笔记。
一 介绍
脚手架开发利器。通过解析参数,注册命令(command)及选项(option),十分便捷的开发自定义的前端脚手架。
二 API
构建一个简单的脚手架测试环境,可以随写随测:
mkdir yarg-learn
cd yarg-learn
npm init -y
npm install yargs --save
// package.json 中配置 bin 属性
"bin": {
"yargs-learn": "/bin/index.js"
}
/**
* /bin/index.js 中写入如下代码
* 配置 api 后,运行 yargs-learn --help 可查看相应的帮助信息
* 或者在代码里 console.log() 想看的信息
*/
#!/usr/bin/env node
const yargs = require("yargs/yargs");
const { hideBin } = require("yargs/helpers");
const arg = hideBin(process.argv);
yargs(arg)
.usage('Usage: yargs-learn [command] <options>')
... // test api
.argv;
注:
一般命令组成为: 主命令 command --option option-param
主命令, 即为 package.json 里配置的 bin 属性里的 key。
command, 为一般要实现的命令。
option, 选项,在命令语句中要 --option 使用,如果有别名则也可以 -alias,如 yargs-learn --help 等同于 yargs-learn -h
option-param, option 的参数
脚手架测试环境搭建具体详情可以参看:前端脚手架实现原理。
1 command
注册命令。
.command(cmd, desc, [builder], [handler])
cmd 为命令的名字; desc 为该命令的说明;[builder],生成器,用来注入命令所接受的选项,可以是一个对象,也可以是一个函数,接受 yargs 对象作为参数;[handler],一个函数,接受argv作为参数,命令执行后要做什么操作,可以在该函数内实现。
.command('get', 'get something', (yargs) => {
yargs.option('url', {
type: 'string',
alias: 'u',
default: 'http://yargs.js.org/',
description: 'yargs website'
})
}, (argv) => {
console.log('argv', argv);
})
.command({
command: 'list [number]',
aliases: ['ls','ll'], // 命令别名
description: 'list description',
builder: (yargs) => {},
handler: (argv) => { console.log(argv); }
})
2 options
注册选项。
.option(key, [opt])
.options(key, [opt])
// 单个注册
.option('f', {
alias: 'file',
demandOption: true,
default: '/etc/passwd',
describe: 'x marks the spot',
type: 'string'
})
// 多个注册
.options({
debug: {
type: 'Boolean',
description: 'debug 模式',
alias: 'd'
},
hideCli: {
type: 'Boolean',
hidden: true, // 隐藏命令不对外使用
description: '隐藏命令'
}
})
3 usage
用来描述语法。
.usage(<message|command>, [desc], [builder], [handler])
只接收一个字符串时,该字符串可以任意填写,一般用来描述命令的语法。
.usage() 也可以用来作 .command()使用(.usage() acts as an alias for .command()),设置默认的命令。
// 语法格式
.usage('Usage: yargs-learn [command] <options>')
// as an alias for .command() 时,第一个参数必须是以 $0 开头, $0 代表主命令。
// .positional() 功能等同于.option(), 不同的是 .positional() 只能在 [builder] 回调中使用
.usage('$0 <port>', 'start the application server', (yargs) => {
yargs.positional('port', {
describe: 'the port that your application should bind to',
type: 'number'
})
}).argv
4 alias
设置option别名。
.alias('h', 'help')
一般在 .command() 和 .options() 中就可以为 option 设置别名。如果别名重复,则会覆盖。
5 wrap
设置输出内容的宽度。接受一个 number 类型的参数。
设为yargs(arg).terminalWidth(),为输出设备的最大宽度。
.wrap(number)
6 strict
严格模式, 输入错误的 option 时,会提示错误
.strict()
7 demandCommand
输入的命令个数,及个数不满足时的提示信息。
.demandCommand([min=1], [minMsg])
.demandCommand([min=1], [max], [minMsg], [maxMsg])
.demandCommand(1, 'You need at least one command before moving on')
8 epilogue
结尾提示。
.epilogue(str)
.epilogue('for more information, find our manual at http://example.com')
9 group
option 分组。
.group(key(s), groupName)
.group('version', 'Global Options')
.group(['help', 'version'], 'Global Options')
10 recommendCommands
在找不到命令时推荐一个名称类似的命令。
.recommendCommands()
11 fail
出现错误时的回调。
.fail(fn | boolean)
.fail(function (msg, err, yargs) {
if (err) throw err // preserve stack
console.error('You broke it!')
console.error(msg)
console.error('You should be doing', yargs.help())
process.exit(1)
})
// 防止yargs退出并打印失败消息
.fail(false)
parse
yargs(arg).argv 等于 yargs().parse(arg)。
.parse([args], [context], [parseCallback])
三 测试代码
#!/usr/bin/env node
const yargs = require("yargs/yargs");
const { hideBin } = require("yargs/helpers");
/**
* hideBin 用来解析参数, hideBin(process.argv) == process.argv.slice(2)。
* require("yargs/yargs").hideBin == require("yargs/helpers").hideBin
*/
const arg = hideBin(process.argv);
console.log(yargs(arg).argv)
console.log(yargs().parse(arg))
yargs(arg)
.usage('Usage: yargs-learn [command] <options>') // 标识语法格式
.demandCommand(1, 'A command is required') // 最少的命令个数,及个数不够时的提示
.strict() // 严格模式, 输入错误的 option 时,会提示错误
.alias('v', 'version') // 注册别名 别名如果重复,会出现覆盖的情况
.alias('h', 'help')
//.wrap(500)
.wrap(yargs(arg).terminalWidth()) // terminal宽度 接收number类型的参数
.epilogue('footer description') // 结尾提示
// 添加 option
// .option('debug', {
// type: 'Boolean',
// description: 'debug 模式',
// alias: 'd'
// })
.options({
debug: {
type: 'Boolean',
description: 'debug 模式',
alias: 'd'
},
hideCli: {
type: 'Boolean',
hidden: true, // 隐藏命令不对外使用
description: '隐藏命令'
}
})
.group(['version'], 'Global Options') // 分组 参数:(option, 组名)
.group(['help'], 'Global Options')
.command(
'init [name]', // command [options]
'init project', // description
// builder 在命令执行之前处理
(yargs) => {
yargs.option('name', {
type: 'string',
description: 'name project',
alias: 'n'
})
},
// handler 命令执行之后处理
(argv) => {
console.log('argv', argv);
}
)
.command({
command: 'list [number]',
aliases: ['ls','ll'],
description: 'list description',
builder: (yargs) => {},
handler: (argv) => { console.log(argv); }
})
.recommendCommands() // 在找不到命令时推荐一个名称类似的命令
// 失败处理,须搭配 recommendCommands 使用
.fail((err, msg) => {
console.log('err', err);
console.log('msg', msg);
})
.argv;