该学习笔记主要记录从零基础完成一个前端工具cli的开发,开发一个cli大致需要几步,输出版本号,加入一些命令行,拉代码,完成。下面逐一了解开发工具。
const program = require("commander");
// 通过version定义版本号
program.version('1.0.0');
// parse方法用来解析命令行中传入的参数
program.parse(process.argv);
也可以借助chalk字体样式在控制台改变工具,获取本地package.json文件中的版本号,使用此方法需要提前使用npm初始化一个项目,方便获取package.json中的版本号。
const program = require("commander");
const pkg = require("../package");
const chalk = require("chalk");
program.version(chalk.green(`${pkg.version}`));
在控制台运行上述文件 node index.js -V
就会输出版本号。
使用格式如下:
.option(’-n, --name [p2]’, ‘描述’, ‘默认值’)
n和name分别是短长定义(可以认为n是name的简写);
p代表选项后面跟着的参数,< >必填,[ ]选填;
最后两个参数分别是描述文案和选项的默认值;
const program = require("commander");
program.version('1.0.0');
program.option('-d --debug', '我的调试');
program.parse(process.argv);
console.log(program.debug, 'debug-----');
// 在cmd输入值
node index -d 输出 // true debug-----
node index --debug 输出 // true debug-----
node index 输出 // undefined debug-----
const program = require("commander");
program.version('1.0.0');
program.option('-d, --debug', '我的调试', '默认值');
program.parse(process.argv);
console.log(program.debug, 'debug-----');
// 在cmd输入值
node index -d 输出 // 默认值 debug-----
node index --debug 输出 // 默认值 debug-----
node index 输出 // undefined debug-----
const program = require("commander");
program.version('1.0.0');
program.option('-d, --debug [p]', '我的调试', '默认值');
program.parse(process.argv);
console.log(program.debug, 'debug-----');
// 在cmd输入
node index -d 输出 // 默认值 debug-----
node index -d 123 输出 // 123 debug-----
const program = require("commander");
program.version('1.0.0');
program.option('-d, --debug <p>', '我的调试', '默认值');
program.parse(process.argv);
console.log(program.debug, 'debug-----');
// 在cmd输入
node index -d 输出 // error: option `-d, --debug <p>' argument missing debug-----
node index -d 123 输出 // 123 debug-----
const program = require("commander");
program.version("1.0.0");
program
.option("-d, --debug", "我的调试")
.option("-h, --help", "测试帮助");
program.parse(process.argv);
console.log(program.opts(), "debug-----");
// 在cmd输入
node index -dh
用 -hd 运行命令等价于 -h -d,如下:
{ version: '1.0.0', debug: true, help: undefined } debug-----
在选项前面加上 no- ,默认返回值则为fasle
const program = require("commander");
program.version("1.0.0");
program
.option("-d, --no-debug", "我的调试")
.option("-h, --help", "测试帮助");
program.parse(process.argv);
console.log(program.opts(), "debug-----");
// 在cmd输入
node index -dh // { version: '1.0.0', debug: false, help: undefined } debug-----
options的第三个参数还可以是函数(此时第四个值就是默认值),此函数接受两个参数:命令行输入的值和选项默认值,函数处理后的返回结果为最终的解析结果。
const program = require("commander");
function add(val, staticVal){
return val + staticVal;
}
program.version("1.0.0");
program
.option("-d, --debug <p>", '我是测试', add, 678)
.option("-h, --help", "测试帮助");
program.parse(process.argv);
console.log(program.debug, "debug-----");
// 在cmd输入
node index -d 123 // 123678 debug------
// 使用格式
.command('add <num> [params]')
.description('描述')
.alias('简称')
.action(function(){ }) //命令处理函数
比如:
const program = require("commander");
function add(val, staticVal){
return val + staticVal;
}
program.version("1.0.0");
program
.command('init <name> [description] [other...]')
.description('这是一个cmd')
.alias('i')
.option("-d, --debug<p>", '我是测试', add, 678)
.option("-h, --help", "测试帮助")
.action(function(name, description, other, cmdObj){
console.log(name, 'name');
console.log(description, 'description');
console.log(other, 'other');
console.log(cmdObj, 'cmdObj');
});
program.parse(process.argv);
// 在cmd输入
node bin/cli i ceshiming desc 1 2 -d 23
// 输出结果依次是
ceshiming name
desc description
[ '1', '2' ] other
Command {
commands: [],
options: [
Option {
flags: '-d, --debug<p>',
required: true,
optional: false,
bool: true,
short: '-d',
long: '--debug<p>',
description: '我是测试',
defaultValue: 678
},
Option {
flags: '-h, --help',
required: false,
optional: false,
bool: true,
short: '-h',
long: '--help',
description: '测试帮助'
}
],
_execs: {},
_allowUnknownOption: false,
_args: [
{ required: true, name: 'name', variadic: false },
{ required: false, name: 'description', variadic: false },
{ required: false, name: 'other', variadic: true }
],
_name: 'init',
_noHelp: false,
parent: Command {
commands: [ [Circular] ],
options: [ [Option] ],
_execs: {},
_allowUnknownOption: false,
_args: [],
_name: 'cli',
Command: [Function: Command],
Option: [Function: Option],
_version: '1.0.0',
_versionOptionName: 'version',
_events: [Object: null prototype] {
'option:version': [Function],
'command:init': [Function: listener],
'command:i': [Function: listener]
},
_eventsCount: 3,
rawArgs: [
'C:\\Program Files\\nodejs\\node.exe',
'E:\\study\\react日常练习\\my-cli\\bin\\cli',
'i',
'ceshiming',
'desc',
'1',
'2',
'-d',
'23'
],
args: [ 'ceshiming', 'desc', [Array], [Circular] ]
},
_description: '这是一个cmd',
_argsDescription: undefined,
_alias: 'i',
'debug<p>': '23678',
_events: [Object: null prototype] {
'option:debug<p>': [Function],
'option:help': [Function]
},
_eventsCount: 2
} cmdObj
使用格式如下:
command('add [params]', 'install description', opts)
一些简单输出东西,不需要加option和command也能输出东西,可以使用arguments
const program = require("commander");
program.version("1.0.0");
program
.arguments('<cmd> [env]')
.action(function(cmd, env, cmdObj){
console.log(cmd, 'cmd');
console.log(env, 'env');
console.log(cmdObj, 'cmdObj');
});
program.parse(process.argv);
// 在cmd输入
node bin/cli 11 23
输出
// 11 cmd
23 env
// 在cmd输入
node bin/cli --help
// 输出
Usage: cli [options] [command]
Options:
-V, --version output the version number
-h, --help output usage information
Commands:
init|i [options] <name> [description] [other...] 这是一个cmd
如果觉得用法说明不够详细,可以监听–help事件
program.on('--help', function() { console.log('这里写你的用法说明文档');});
const program = require("commander");
function add(val, staticVal) {
return val + staticVal;
}
program.version("1.0.0");
program
.on("--help", function () {
console.log("-d, 测试");
})
.command("init <name> [description] [other...]")
.description("这是一个cmd")
.alias("i")
.option("-d, --debug<p>", "我是测试", add, 678)
.option("-t, --text", "测试帮助")
.action(function (name, description, other, cmdObj) {
console.log(name, "name");
});
program.parse(process.argv);
// cmd 输入 node bin/cli -h
Usage: cli [options] [command]
Options:
-V, --version output the version number
-h, --help output usage information
Commands:
init|i [options] <name> [description] [other...] 这是一个cmd
-d, 测试
program.name("命令名称").usage("选项参数顺序说明");
const program = require("commander");
function add(val, staticVal) {
return val + staticVal;
}
program.name("命令名称").usage("选项参数顺序说明");
program.version("1.0.0");
program.on("--help", function () {
console.log("-d, 测试");
});
program
.command("init <name> [description] [other...]")
.option("-t, --text", "测试帮助")
.action(function (name, description, other, cmdObj) {
console.log(name, "name");
});
program.parse(process.argv);
// node bin/cli -h
Usage: 命令名称 选项参数顺序说明
Options:
-V, --version output the version number
-h, --help output usage information
Commands:
init [options] <name> [description] [other...]
-d, 测试
npm install ora
const ora = require("ora");
const spinner = ora("默认展示信息");
spinner.start('实际显示内容');
执行该文件就会在cmd看到下载指示,|实际显示内容
注意: 如果没有start中内容,默认就会显示默认值,后续使用spinner.text更新文字无效
const ora = require("ora");
const spinner = ora("默认展示信息");
spinner.start();
setTimeout(() => {
spinner.color = 'yellow';
spinner.text = '更新显示内容';
}, 1000);
// 1s后旋转图标变色,文字改变
参数名称 | 参数类型 | 参数含义 | 默认值 | 使用方法 |
---|---|---|---|---|
text | string | 在微调器之后显示的文本。 | - | spinner({text: ‘文本’}) |
prefixText | string|()=>string | 文本或返回文本以在微调器之前显示的函数。如果设置为空字符串,则不会显示任何前缀文本。 | - | spinner({prefixText: ‘’}) |
spinner | string|object | 旋转器,显示的形状 | dots | spinner({spinner: { interval: 80, // 可选frames: [’-’, ‘+’, ‘-’] }}); //其中frames为图标动态展示形状,如果为数组,会逐个显示数组中的内容 |
color | string | 图标颜色 | cyan | spinner({color: ‘magenta’}) |
hideCursor | boolean | 隐藏光标 | true | spinner.hideCursor=“false” |
indent | number | 缩进 | 0 | spinner.indent=6 |
interval | number | 间隔,每帧间隔 | 100 |
const spinner=ora({color: 'red', text: '测试'});
名称 | 用法 | 含义 |
---|---|---|
.start(text?) | spinner.start(‘开始了’) | 开始微调器,其中参数后问好表示选填参数,可有可无。 |
.stop() | spinner.stop() | 停止并清除微调器。返回实例。 |
.succeed(text?) | spinner.succcess(‘下载成功’) | 停止微调器,将其更改为绿色✔ 并保留当前文本,或者text 如果提供。返回实例。 |
.fail(text?) | 失败 | 停止微调器,将其更改为红色✖ 并保留当前文本,或者text 如果提供。返回实例。 |
.warn(text?) | 警告 | 停止微调器,将其更改为黄色⚠ 并保留当前文本,或者text 如果提供。返回实例。 |
.info(text?) | 停止微调器,将其更改为蓝色ℹ 并保留当前文本,或者text 如果提供。返回实例。 | |
.isSpinning | 在旋转 | 实例当前是否正在旋转的布尔值。 |
.stopAndPersist(options?) | spinner.stopAndPersist({text: ‘停止’}) | 停止微调器并更改符号或文本。返回实例。 |
.clear() | spinner.clear() | 清除微调器。返回实例。 |
.render() | spinner.render() | 手动渲染新帧。返回实例。 |
.frame() | spinner.frame() | 获取当前显示的frame信息 |
参数名 | 类型 | 默认值 | 含义 | 用法 |
---|---|---|---|---|
symbol | string | ‘’ | 用于替换微调器的符号。 | |
text | string | text | 要在符号后保留的文本 | |
prefixText | string | prefixText | 要保留在符号之前的文本。如果设置为空字符串,则不会显示任何前缀文本。 |
可以使用download-git-repo
插件来拉取git代码
npm install download-git-repo
download(repository, destination, options, callback)
从以下位置下载存储库的速记存储库字符串:
github:owner/name
或者干脆owner/name
gitlab:owner/name
bitbucket:owner/name
该repository
参数默认为master
分支,也可以指定分支名称,如owner/name#my-branch
. 除了指定下载位置的类型外,您还可以指定自定义来源,如gitlab:custom.com:owner/name
. 除非指定了协议,否则自定义来源将分别默认为https
或git@
用于 http 和克隆下载。随意提交问题或拉取请求以获取其他来源选项。
除了拥有支持的 git 主机的简写外,您还可以直接使用以下命令访问存储库:
direct:url
这将绕过速记规范器并url
直接通过。如果direct
不使用克隆,您必须将完整的 url 传递给 zip 文件,如果需要,包括分支的路径。如果direct
与 clone 一起使用,则必须将完整 url 传递给 git repo,并且可以指定一个分支,如direct:url#my-branch
.
将存储库下载到的文件路径。
带有下载选项的可选选项对象参数。选项包括:
clone
- 布尔默认值false
- 如果为 true,则使用git clone
而不是 http 下载。虽然这可能会慢一点,但如果设置了适当的 SSH 密钥,它确实允许使用私有存储库。回调函数为function (err)
.
假如想要拉取github上一个项目,该项目所有者github的用户名为lingge,他里边项目为todoList,则可以使用如下命令:
const download = require("download-git-repo");
download('github:lingge/todoList', './linges', {clone: true}, function(err){if(!err){
console.log('下载成功');
}});
或者你只有一个git连接地址,其他都不知道,可以使用如下方式:
const download = require("download-git-repo");
download('direct:https://github.com/lingge/todoList.git', './linges', {clone: true}, function(err){if(!err){
console.log('下载成功');
}});
注意:上述git地址为虚假的,使用时候改为自己的,由于没有用ora状态来显示当前下载状态,如果网速有波动说明后台在下载,等待一会就好
chalk
是一个可以修改终端输出字符样式的 npm
包。
npm install chalk
const chalk = require('chalk');
const log = console.log;
log(chalk.red.bold.underline('欢迎使用', '好好用'))
// 输入内容为字体红色,加粗,带下划线。
chalk.[.<style>...](string, [string...])
其中<>中为必输,其他为可选。如果多个样式有冲突,以后边为准。
此选项用来修改默认支持颜色级别,可以修改,建议不要全局做出修改,以免影响别的模块使用。在自己模块中使用如下类覆盖样式支持级别。
const ctx = new chalk.Instance({level: 0});
等级 | 描述 |
---|---|
0 | 禁用所有颜色 |
1 | 基本颜色支持(16 色) |
2 | 256色支持 |
3 | 真彩色支持(1600 万色) |
chalk.supportsColor
reset
- 重置当前的颜色链。bold
- 使文本加粗。dim
- 仅发出少量光。italic
- 使文本斜体。(不广泛支持)underline
- 使文本下划线。(不广泛支持)inverse
- 反转背景和前景色。hidden
- 打印文本,但使其不可见。strikethrough
- 在文本中心放置一条水平线。(不广泛支持)visible
- 仅当 Chalk 的颜色级别 > 0 时才打印文本。对于纯粹装饰性的东西很有用。black
red
green
yellow
blue
magenta
cyan
white
blackBright
(别名:gray
,grey
)redBright
greenBright
yellowBright
blueBright
magentaBright
cyanBright
whiteBright
bgBlack
bgRed
bgGreen
bgYellow
bgBlue
bgMagenta
bgCyan
bgWhite
bgBlackBright
(别名:bgGray
,bgGrey
)bgRedBright
bgGreenBright
bgYellowBright
bgBlueBright
bgMagentaBright
bgCyanBright
bgWhiteBright
以下例子输出内容相同。
console.log(chalk.bold.rgb(10, 100, 200)('Hello!'));
console.log(chalk.bold.rgb(10, 100, 200)`Hello!`);
console.log(chalk`{bold.rgb(10,100,200) Hello!}`);
也就是chalk.blod.rgb===chalk`{bold.rgb}`
Chalk在支持的终端应用程序上支持 256 色和Truecolor(1600 万色)。
颜色从 1600 万 RGB 值缩减为终端仿真器支持的 ANSI 颜色格式(或通过指定{level: n}
为 Chalk 选项)。例如,配置为在级别 1(基本颜色支持)运行的 Chalk 会将 #FF0000(红色)的 RGB 值下采样到 31(ANSI 转义红色)。
例子:
chalk.hex('#DEADED').underline('Hello, world!')
chalk.keyword('orange')('Some orange text')
chalk.rgb(15, 100, 204).inverse('Hello!')
这些模型的背景版本以bg
模块的第一级为前缀,并且大写(例如keyword
,前景色和bgKeyword
背景色)。
chalk.bgHex('#DEADED').underline('Hello, world!')
chalk.bgKeyword('orange')('Some orange text')
chalk.bgRgb(15, 100, 204).inverse('Hello!')
可以使用以下颜色模型:
rgb
- 例子: chalk.rgb(255, 136, 0).bold('Orange!')
hex
- 例子: chalk.hex('#FF8800').bold('Orange!')
keyword
(CSS 关键字) - 示例: chalk.keyword('orange').bold('Orange!')
hsl
- 例子: chalk.hsl(32, 100, 50).bold('Orange!')
hsv
- 例子: chalk.hsv(32, 100, 100).bold('Orange!')
hwb
- 例子: chalk.hwb(32, 0, 50).bold('Orange!')
ansi
- 例子: chalk.ansi(31).bgAnsi(93)('red on yellowBright')
ansi256
- 例子: chalk.bgAnsi256(194)('Honeydew, more or less')
const chalk = require('chalk');
const log = console.log;
log(chalk`{bgRgb(255, 255, 255).yellow hello {bold 加粗文字}是不是{red 红色文字}}`);
使用模板整体背景色为白色,然后,整体字体为黄色,
启动项目时候,如果没有进度显示,项目很大也不知道进度被卡住了,还是没有编译完。使用webpack-progress-ora-plugin
插件来解决这个问题。也可以使用webpackbar
插件来解决,具体看自己喜好。
最后:所有开发cli的基础知识到此都已经将完了,可以愉快的去写cli了