脚手架框架之yargs的基础核心特性与应用
1 )概述
- yargs 是脚手架当中使用量非常大的一个框架
- 进入它的npm官网: https://www.npmjs.com/package/yargs
- 目前版本: 17.7.2
- Weekly Downloads: 71,574,188 (动态数据)
- 最近更新:last month (github)
- 说明这是一个比较优质的库
2 )对 yargs 的应用
- 准备一个脚手架工程,比如 xyzcli
- 进行 npm 初始化 $
npm init -y
- 修改package.json中的关键配置
- 添加 bin 属性,其值设置为: "bin/index.js"
- 在脚手架工程目录中执行安装开发依赖
- $
npm i yargs -S
- $
2.1 初步实践,了解其基本API
-
编写 bin/index.js
js#!/usr/bin/env node const yargs = require('yargs/yargs'); const { hideBin } = require('yargs/helpers'); console.log(hideBin(process.argv)); yargs();
- 现在执行 $
npm link
方便调试 - 执行 $
xyzcli --help
, 可以看到输出[ '--help' ]
- 现在执行 $
2.2 继续优化,窥探其基本用法
-
好,接着修改 bin/index.js
js#!/usr/bin/env node const yargs = require('yargs/yargs'); const { hideBin } = require('yargs/helpers'); // 用于参数解析 const arg = hideBin(process.argv); yargs(arg) .argv;
-
现在执行 $
xyzcli --help
可以看到输出shell选项: --help 显示帮助信息 [布尔] --version 显示版本号 [布尔]
-
执行 $
xyzcli --version
shell1.0.0
-
这时候说明最简易版脚手架已经开发好了
2.3 探究 strict
模式
-
现在发现差异,如果执行 $
xyzcli --help
有输出 -
但是执行 $
xyzcli -h
就没有输出了 -
可以加入 strict 模式,可以对无用参数输入进行提示,如下添加
jsyargs(arg) .strict() .argv;
-
继续执行 $
xyzcli -h
看到输出了报错提示shell选项: --help 显示帮助信息 [布尔] --version 显示版本号 [布尔] 无法识别的选项:h
-
注意这个 strict 在 lerna 源码中有用到
2.4 对 usage
这个API的使用
-
继续测试 usage
jsyargs(arg) .usage('Usage: xyzcli [command] <options>') .strict() .argv;
-
执行 $
xyzcli --help
,查看输出shellUsage: xyzcli [command] <options> 选项: --help 显示帮助信息 [布尔] --version 显示版本号 [布尔]
-
看到,最顶部多了
Usage: xyzcli [command] <options>
2.5 对 demandCommand
这个API的使用
-
这个API表示最少输入多少命令
jsyargs(arg) .usage('Usage: xyzcli [command] <options>') .demandCommand(1, 'A command is required. Pass --help to see all available commands and options.') .strict() .argv;
-
只执行 $
xyzcli
, 可查看输出shellUsage: xyzcli [command] <options> 选项: --help 显示帮助信息 [布尔] --version 显示版本号 [布尔] A command is required. Pass --help to see all available commands and options.
-
可以发现,最后多了一行
A command is required. Pass --help to see all available commands and options.
-
这个API就可以对命令参数过少时进行提示
2.6 对 alias
这个API的使用
-
对现有命令或参数起别名
jsyargs(arg) .usage('Usage: xyzcli [command] <options>') .demandCommand(1, 'A command is required. Pass --help to see all available commands and options.') .strict() .alias('h', 'help') .alias('v', 'version') .argv;
-
对
-h
进行测试,执行 $xyzcli -h
,输出shellUsage: xyzcli [command] <options> 选项: -h, --help 显示帮助信息 [布尔] -v, --version 显示版本号 [布尔]
-
对
-v
进行测试,执行 $xyzcli -v
,输出shell1.0.0
2.7 对 wrap
这个API的使用
-
对终端cli窗口的宽度的设定
jsyargs(arg) .usage('Usage: xyzcli [command] <options>') .demandCommand(1, 'A command is required. Pass --help to see all available commands and options.') .strict() .alias('h', 'help') .alias('v', 'version') .wrap(50) // 这里设定为 50 .argv;
-
执行 $
xyzcli -h
,查看宽度shellUsage: xyzcli [command] <options> 选项: -h, --help 显示帮助信息 [布尔] -v, --version 显示版本号 [布尔]
-
修改宽度为 80
js.wrap(80) // 这里设定为 80
-
再次执行 $
xyzcli -h
,查看宽度shellUsage: xyzcli [command] <options> 选项: -h, --help 显示帮助信息 [布尔] -v, --version 显示版本号 [布尔]
-
可以看到两者不同宽度的区别
-
如果想要占满终端屏幕, 可以使用
terminalWidth()
jsconst cli = yargs(arg) cli .usage('Usage: xyzcli [command] <options>') .demandCommand(1, 'A command is required. Pass --help to see all available commands and options.') .strict() .alias('h', 'help') .alias('v', 'version') .wrap(cli.terminalWidth()) // 这里 .argv;
-
terminalWidth()
会返回终端宽度,这里没有必要做演示了,会铺满终端
2.8 对 epilogue
这个API的使用
-
它可以在结尾加上我们想要说的话
jsconst cli = yargs(arg) cli .usage('Usage: xyzcli [command] <options>') .demandCommand(1, 'A command is required. Pass --help to see all available commands and options.') .strict() .alias('h', 'help') .alias('v', 'version') .wrap(cli.terminalWidth()) .epilogue('We hope you guys work happily every day!') // 注意这里 .argv;
-
执行 $
xyzcli -h
, 查看输出shellUsage: xyzcli [command] <options> 选项: -h, --help 显示帮助信息 [布尔] -v, --version 显示版本号 [布尔] We hope you guys work happily every day!
-
可以看到最后一行,输出
We hope you guys work happily every day!
-
结合
dedent
库来使用,首先进行安装,$npm i dedent -S
-
基于 dedent 库来设定 epilogue, 达成去除缩进(包含首位空格)的目的
js#!/usr/bin/env node const yargs = require('yargs/yargs'); const { hideBin } = require('yargs/helpers'); const dedent = require('dedent'); // 注意这里 const arg = hideBin(process.argv); const cli = yargs(arg) cli .usage('Usage: xyzcli [command] <options>') .demandCommand(1, 'A command is required. Pass --help to see all available commands and options.') .strict() .alias('h', 'help') .alias('v', 'version') .wrap(cli.terminalWidth()) .epilogue(dedent` Welcome to use xyzcli command line. We hope you guys work happily every day! For more information, please visit: https://xxx.com/xxx/xyzcli `) .argv;
-
执行 $
xyzcli -h
,查看输出shellUsage: xyzcli [command] <options> 选项: -h, --help 显示帮助信息 [布尔] -v, --version 显示版本号 [布尔] Welcome to use xyzcli command line. We hope you guys work happily every day! For more information, please visit: https://xxx.com/xxx/xyzcli
2.9 对 options
这个API的使用
-
全局选项,对所有 command 都有效
jsconst cli = yargs(arg) cli .usage('Usage: xyzcli [command] <options>') .demandCommand(1, 'A command is required. Pass --help to see all available commands and options.') .strict() .alias('h', 'help') .alias('v', 'version') // .alias('d', 'debug') // 这个设置别名,同下面,二者取其一即可 .wrap(cli.terminalWidth()) .epilogue(dedent` Welcome to use xyzcli command line. We hope you guys work happily every day! For more information, please visit: https://xxx.com/xxx/xyzcli `) .options({ debug: { type: 'boolean', describe: 'Bootstrap debug mode', alias: 'd' // 这里添加了,上面就可以忽略了,推荐写在这里 } }) .argv;
-
这里设置了 options,内部传入一个对象进行配置,这里别名的两种设置方式,推荐下面这种,在options内部设定
-
执行 $
xyzcli -h
, 查看输出结果shellUsage: xyzcli [command] <options> 选项: -d, --debug Bootstrap debug mode [布尔] -h, --help 显示帮助信息 [布尔] -v, --version 显示版本号 [布尔] Welcome to use xyzcli command line. We hope you guys work happily every day! For more information, please visit: https://xxx.com/xxx/xyzcli
-
可见,这里添加了 -d 和 --debug 的选项
2.10 对 option
这个API的使用
-
这个 option 和 options 这两个API用途差不多, 但使用方式不一样
jsconst cli = yargs(arg) cli .usage('Usage: xyzcli [command] <options>') .demandCommand(1, 'A command is required. Pass --help to see all available commands and options.') .strict() .alias('h', 'help') .alias('v', 'version') // .alias('d', 'debug') .wrap(cli.terminalWidth()) .epilogue(dedent` Welcome to use xyzcli command line. We hope you guys work happily every day! For more information, please visit: https://xxx.com/xxx/xyzcli `) .options({ debug: { type: 'boolean', describe: 'Bootstrap debug mode', alias: 'd' // 这里添加了,上面就可以忽略了,推荐写在这里 } }) .option('registry', { type: 'string', describe: 'Define global registry', alias: 'r', // hidden: true, // 这个就不会出现在提示中,但是可以作为开发调试使用 --registry 或 -r }) .argv;
-
option 这个API,可以配置 hidden 选项,这个配置之后,不会出现在终端提示中,但是可作为开发调试使用,$
xyzcli -r
- 需要后期结合这个参数做对应的处理程序,这块先略过
- 同时,需注意,options 中是没有 hidden 配置选项的
-
执行 $
xyzcli -h
,查看输出结果shellUsage: xyzcli [command] <options> 选项: -d, --debug Bootstrap debug mode [布尔] -r, --registry Define global registry [字符串] -h, --help 显示帮助信息 [布尔] -v, --version 显示版本号 [布尔] Welcome to use xyzcli command line. We hope you guys work happily every day! For more information, please visit: https://xxx.com/xxx/xyzcli A command is required. Pass --help to see all available commands and options.
2.11 对 group
这个API的使用
-
对命令进行分组管理, 这次全量代码都在这里
js#!/usr/bin/env node const yargs = require('yargs/yargs'); const { hideBin } = require('yargs/helpers'); const dedent = require('dedent'); const arg = hideBin(process.argv); const cli = yargs(arg) cli .usage('Usage: xyzcli [command] <options>') .demandCommand(1, 'A command is required. Pass --help to see all available commands and options.') .strict() .alias('h', 'help') .alias('v', 'version') // .alias('d', 'debug') .wrap(cli.terminalWidth()) .epilogue(dedent` Welcome to use xyzcli command line. We hope you guys work happily every day! For more information, please visit: https://xxx.com/xxx/xyzcli `) .options({ debug: { type: 'boolean', describe: 'Bootstrap debug mode', alias: 'd' // 这里添加了,上面就可以忽略了,推荐写在这里 } }) .option('registry', { type: 'string', describe: 'Define global registry', alias: 'r', // hidden: true, // 这个就不会出现在提示中,但是可以作为开发调试使用 --ci }) .group(['debug'], '开发选项:') .group(['registry'], '其他选项:') .argv;
-
执行 $
xyzcli -h
,查看输出结果shellUsage: xyzcli [command] <options> 开发选项: -d, --debug Bootstrap debug mode [布尔] 其他选项: -r, --registry Define global registry [字符串] 选项: -h, --help 显示帮助信息 [布尔] -v, --version 显示版本号 [布尔] Welcome to use xyzcli command line. We hope you guys work happily every day! For more information, please visit: https://xxx.com/xxx/xyzcli
-
可以看到 Dev Options 这一分组,把 debug 包含进去了,剩余其他的都在 选项中
3 )参考 lerna 的实现细节