必知必会的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);
}); 
复制代码
必知必会的Node-CLI开发基础

当然交互界面的元素并不只有这一种,在使用各类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()
})
复制代码
必知必会的Node-CLI开发基础

三、定制样式

为了有效的区别命令行界面中信息的差异性,我们可以为这里输出信息添加适当的样式。

这里介绍一下字符串添加样式的语法:

\x1b[背景颜色编号;字体颜色编号m
复制代码

每条样式都要以\x1b[开头:

// \x1b[0m 清除样式
  process.stdout.write('\x1b[44;37m OK \x1b[0m just do it\n')
复制代码
必知必会的Node-CLI开发基础

四、自定义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风格的子命令;
  • 自动化的帮助信息;
  • ....

那么下面这些成熟的框架会给你很大的帮助:


以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

高性能网站建设指南(第二版)

高性能网站建设指南(第二版)

Steve Souders / 刘彦博 / 电子工业出版社 / 2015-5 / 55.00元

《高性能网站建设指南:前端工程师技能精髓》结合Web 2.0以来Web开发领域的最新形势和特点,介绍了网站性能问题的现状、产生的原因,以及改善或解决性能问题的原则、技术技巧和最佳实践。重点关注网页的行为特征,阐释优化Ajax、CSS、JavaScript、Flash和图片处理等要素的技术,全面涵盖浏览器端性能问题的方方面面。在《高性能网站建设指南:前端工程师技能精髓》中,作者给出了14条具体的优化......一起来看看 《高性能网站建设指南(第二版)》 这本书的介绍吧!

URL 编码/解码
URL 编码/解码

URL 编码/解码

RGB HSV 转换
RGB HSV 转换

RGB HSV 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具