必知必会的Node-CLI开发基础
栏目: JavaScript · 发布时间: 7年前
内容简介:在NodeJS中可以通过以下代码获取命令行中传递的参数:但是这对于构建一个CLI工具远远不够,首先需要考虑参数输入的各种风格:这里可以通过正则表达式对process.argv进行加工:
在NodeJS中可以通过以下代码获取命令行中传递的参数:
process.argv.slice(2) 复制代码
但是这对于构建一个CLI工具远远不够,首先需要考虑参数输入的各种风格:
- Unix参数风格:前面加-,不过后面跟的是单个字符,例如-abc解析为['a', 'b', 'c']。
- GNU参数风格:前面加--,例如npm中的命令,npm --save-dev webpack。
- BSD参数风格:前面不加修饰符。
这里可以通过正则表达式对process.argv进行加工:
/**
* 解析Unix、BSD和GNU参数风格
* @param {Array} argv 命令行参数数组
* @returns
*/
function parseArgv (argv) {
const max = argv.length
const result = {
_: []
}
for (let i = 0; i < max; i++) {
const arg = argv[i]
const next = argv[i + 1]
if (/^--.+/.test(arg)) {
// GNU风格
const key = arg.match(/^--(.+)/)[1]
if (next != null && !/^-.+/.test(next)) {
result[key] = next
i++
} else {
result[key] = true
}
} else if (/^-[^-]+/.test(arg)) {
// Unix风格
const items = arg.match(/^-([^-]+)/)[1].split('')
for (let j = 0, max = items.length; j < max; j++) {
const item = items[j]
// 非字母不解析
if (!/[a-zA-Z]/.test(item)) {
continue
}
if (next != null && !/^-.+/.test(next) && j === max - 1) {
result[item] = next
i++
} else {
result[item] = true
}
}
} else {
// BSD风格
result._.push(arg)
}
}
return result
}
复制代码
通过以上的方法可以得到如下结果:
node example1.js --save-dev -age 20 some
// => 结果
{
_: ['some'],
'save-dev': true,
a: true,
g: true,
e: 20
}
复制代码
上面这个示例不仅仅为了展示解析的结果,而且还强调了Unix参数风格只解析单个字母,所以这种风格的参数可能表达的意思不太明确并且数量有限,那么就需要在正确的场景中使用这种风格的参数:
npm --save-dev webpack npm -D webpack 复制代码
npm中采用Unix参数风格表示简写,这就是一种很恰当的方式,那么前面示例中的-age按照语义应该改为--age更加合理一点。
二、命令行界面
NodeJS中的readline模块提供question和prompt方法构建命令行界面,下面是一个简单的问答式的交互界面:
const readline = require('readline');
const question = ['请输入您的姓名', '请输入您的年龄']
const result = []
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
prompt: `?${question[0]} `
});
rl.prompt();
rl.on('line', (line) => {
result.push(line.trim())
const max = result.length
if (max === question.length) {
rl.close()
}
rl.setPrompt(`?${question[max]} `)
rl.prompt();
}).on('close', () => {
console.log(`谢谢参与问答 *** 姓名: ${result[0]} 年龄: ${result[1]}`);
process.exit(0);
});
复制代码
当然交互界面的元素并不只有这一种,在使用各类CLI工具时,你应该会遇到诸如:单项选择、下载进度条...
下面可以尝试实现一个单项选择交互界面:
const readline = require('readline')
let selected = 0
const choices = ['javascript', 'css', 'html']
let lineCount = 0
const rl = readline.createInterface(process.stdin, process.stdout)
function reader () {
let str = ''
for (let i = 0; i < choices.length; i++) {
lineCount++
str += `${selected === i ? '[X]' : '[ ]'} ${choices[i]}\r\n`
}
process.stdout.write(str)
}
reader()
process.stdin.on('keypress', (s, key) => {
const name = key.name
const max = choices.length
if (name === 'up' && selected > 0) {
selected--
} else if (name === 'down' && selected < max - 1) {
selected++
} else if (name === 'down' && selected === max - 1) {
selected = 0
} else if (name === 'up' && selected === 0) {
selected = max - 1
} else {
return true
}
// 移动光标,并且删除光标右边的内容
readline.moveCursor(process.stdout, 0, -lineCount)
readline.clearLine(process.stdout, -1)
lineCount -= choices.length
reader()
})
rl.on('line', () => {
console.log(`you choose ${choices[selected]}`)
process.exit(0)
}).on('close', () => {
rl.close()
})
复制代码
三、定制样式
为了有效的区别命令行界面中信息的差异性,我们可以为这里输出信息添加适当的样式。
这里介绍一下字符串添加样式的语法:
\x1b[背景颜色编号;字体颜色编号m 复制代码
每条样式都要以\x1b[开头:
// \x1b[0m 清除样式
process.stdout.write('\x1b[44;37m OK \x1b[0m just do it\n')
复制代码
四、自定义Node命令
接下来就是自定义Node命令,首先需要创建一个命令执行的文件:
// hello.js 首行需要指定脚本的解释程序
#!/usr/bin/env node
console.log('hello')
复制代码
再利用package.json中的bin配置:
{
"bin": {
"hello": "./hello.js"
},
}
复制代码
执行npm的link命令:
npm link # 输入自定义命令 hello # 输出 hello 复制代码
五、总结
上面介绍了开发Node-CLI时所需要的一些基本知识,但是对于用过诸如webpack-cli、vue-cli工具的你可能会发现这些优秀的CLI工具还具有:
- git风格的子命令;
- 自动化的帮助信息;
- ....
那么下面这些成熟的框架会给你很大的帮助:
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- springmvc教程--注解开发基础详解
- C++开发EOS基础指南
- flume 1.8.0 开发基础
- 移动端开发基础知识扫盲
- 业务开发转基础开发,这三种 “高可用” 架构你会么?
- Python开发【第二章】入门基础
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Head First Design Patterns
Elisabeth Freeman、Eric Freeman、Bert Bates、Kathy Sierra、Elisabeth Robson / O'Reilly Media / 2004-11-1 / USD 49.99
You're not alone. At any given moment, somewhere in the world someone struggles with the same software design problems you have. You know you don't want to reinvent the wheel (or worse, a flat tire),......一起来看看 《Head First Design Patterns》 这本书的介绍吧!