node.js命令行教程图文详解


Posted in Javascript onMay 27, 2019

本文先介绍原生的node.js实现命令行交互,了解原生的api,然后通过commander.js和inquirer.js实现一个完整的交互命令行工具。

项目地址

process (进程)

process对象是一个全局变量,它提供了当前node.js进程的信息并对其控制。因为其是一个全局变量所以无需在文件中引入。

需要用到的几个api

  • process.argv
  • process.cwd()
  • process.stdin
  • process.stdout
  • process.stdin.resume()
  • process.argv

process.argv

属性返回一个数组。数组的第一个值是process.execPath,第二个是正在执行的JavaScript的文件路径,其余参数为其它命令参数,这是我们来自定义命令的关键。

示例

新建argv.js

// argv.js
console.log(process.argv)

执行node命令node argv.js

node argv.js --name zhu
## 输出
[ '/usr/local/bin/node', ## 执行当前脚本的Node二进制文件的绝对路径
 '/Users/zhuhuilong/Node/Book/argv.js', ## 文件的绝对路径
 '--name', ## 其余参数
 'zhu' ]

接收自定义的命令参数进行处理输出

// argv.js
console.log(process.argv)

let argvs = process.argv

let param = argvs.splice(2)
if(param[0] && param[0] == '--name'){
 if(param[1]){
 console.log(`hello ${param[1]}`)
 }else{
 console.log('请输入name')
 }
}

运行argv.js

node argv.js --name zhu
## 输出
[ '/usr/local/bin/node',
 '/Users/zhuhuilong/Node/Book/argv.js',
 '--name',
 'zhu' ]
hello zhu
param [ '--name', 'zhu' ]

process.stdin与process.stdout

process.stdin(标准输入)

process.stdin 属性返回连接到 stdin (fd 0) 的流。 它是一个 net.Socket 流(也就是双工流),除非 fd 0 指向一个文件,在这种情况下它是一个可读流。

process.stdout(标准输出)

process.stdout 属性返回连接到 stdout (fd 1) 的流。 它是一个 net.Socket 流(也就是双工流),除非 fd 1 指向一个文件,在这种情况下它是一个可写流。

process.stdin.resume()

  • 一个指向 标准输入流(stdin) 的可读流(Readable Stream)。标准输入流默认是暂停 (pause) 的,所以必须要调用 process.stdin.resume() 来恢复 (resume) 接收。
  • 作为流,process.stdin可以在旧模式下使用。为了兼容node v0.10以前的版本。在旧模式喜爱使用stdin必须调用process.stdin.resume()。注意如果调用了process.stdin.resume() stdin将转为旧模式。

通俗来讲就是控制台等待我们输入内容不退出进程,对输入输出进行交互。

新建inputout.js

// inputout.js
process.stdin.setEncoding('utf8')

let argvs = process.argv

let param = argvs.splice(2)
if (param[0] && param[0] == '--name') {
 if (param[1]) {
 console.log(`hello ${param[1]}`)
 } else {
 process.stdout.write(`请输入name:`)
 process.stdin.resume()
 process.stdin.on('data', chunk => {
  if (!!chunk.replace(/[\r\n]/g, '')) {
  process.stdout.write(`你输入的name是: ${chunk}`)
  process.stdin.emit('end')
  } else {
  process.stdout.write(`请输入name:`)
  }
 })
 }
}

process.stdin.on('end', () => {
 process.stdout.write('结束\n')
})

>执行node inputout.js --name

node.js命令行教程图文详解

node.js命令行教程图文详解

备注

在新版本node模式下可以使用process.stdin.on("readable",()=>{})代替process.stdin.resume()恢复输入流接收。

示例:

process.stdin.on("readable", () => {
 var chunk = process.stdin.read();
 console.log(typeof(chunk))
 if (chunk !==null) {
 process.stdout.write(`data: ${chunk}`);
 process.stdin.emit("end");
 }
});

process.stdin.on("end", () => {
 process.stdout.write("end");
});

从上面的示例我们可以拿到process.argv参数对其进行处理交互,但如果要实现更复杂的命令交互,使用上面的方法会很吃力。下面我们使用commander.js和inquirer来实现一个完整的node命令行工具(创建项目模版)。

commander.js

node.js命令行界面的完整解决方案,受Ruby Commander启发。

commander.js的API简述

program.version() 声明版本

const program = require('commander')
const pkg = require('../package.json')
program.version(pkg.version)

Options 解析

使用.option()方法定义commander的选项options,也可以作为选项的文档。

var program = require('commander');
 
program
 .version('0.1.0')
 .option('-p, --peppers', 'Add peppers')
 .option('-P, --pineapple', 'Add pineapple')
 .option('-b, --bbq-sauce', 'Add bbq sauce')
 .option('-c, --cheese [type]', 'Add the specified type of cheese [marble]', 'marble')
 .parse(process.argv);
 
console.log('you ordered a pizza with:');
if (program.peppers) console.log(' - peppers');
if (program.pineapple) console.log(' - pineapple');
if (program.bbqSauce) console.log(' - bbq');
console.log(' - %s cheese', program.cheese);

添加自定义命令program.command()

var program = require('commander');
 
program
 .command('rm <dir>') //<>必选参数,如果是[]则是可选参数
 .option('-r, --recursive', 'Remove recursively')
 .action(function (dir, cmd) {
 console.log('remove ' + dir + (cmd.recursive ? ' recursively' : ''))
 })
 
program.parse(process.argv)

// command()可变参数
/** 命令command有且只有最后一个参数可变不固定的。 要使参数变量可变,必须将...附加到参数名称。**/
program
 .version('0.1.0')
 .command('rmdir <dir> [otherDirs...]')
 .action(function (dir, otherDirs) {
 console.log('rmdir %s', dir);
 if (otherDirs) {
  otherDirs.forEach(function (oDir) {
  console.log('rmdir %s', oDir);
  });
 }
 });
program.parse(process.argv);

program.action() 定义命令的回调函数

var program = require("commander");

program
 .command("rm <dir>")
 .option("-r, --recursive", "Remove recursively")
 .option("-f, --force", "remove force")
 .action(function(dir, cmd) {
 // cmd为option参数选项
 //console.log('cmd',cmd)
 if (cmd.recursive) {
  console.log("remove " + dir + " recursively");
 }
 if (cmd.force) {
  console.log("remove " + dir + " forcefully");
 }
 });

program.parse(process.argv);

inquirer.js

Inquirer.js 使用NodeJs做的一个通用交互式命令行用户界面的集合。具有常用的控制台交互操作。

node.js命令行教程图文详解

由于交互的问题种类不同,inquirer为每个问题提供很多参数:

  • type:表示提问的类型,包括:input, confirm, list, rawlist, expand, checkbox, password, editor;
  • name: 存储当前问题回答的变量;
  • message:问题的描述;
  • default:默认值;
  • choices:列表选项,在某些type下可用,并且包含一个分隔符(separator);
  • validate:对用户的回答进行校验;
  • filter:对用户的回答进行过滤处理,返回处理后的值;
  • transformer:对用户回答的显示效果进行处理(如:修改回答的字体或背景颜色),但不会影响最终的答案的内容;
  • when:根据前面问题的回答,判断当前问题是否需要被回答;
  • pageSize:修改某些type类型下的渲染行数;
  • prefix:修改message默认前缀;
  • suffix:修改message默认后缀。
  • 创建cli.js
const program = require('commander')
const inquirer = require('inquirer')
const fs = require('fs')
const path = require('path')
const pkg = require('../package.json')

const CWD = process.cwd()

const promptList = [
 {
 type: 'list',
 message: '请选择一种模版',
 name: 'template',
 choices: ['vue', 'angular', 'webpack-m-pages'],
 filter: function(val) {
  return val.toLowerCase()
 }
 }
]

program
 .version(pkg.version)
 .command('create <dir>')
 .description('create project template')
 .action(function(dir, cmd) {
 const TEMPLATE_PATH = path.join(CWD, dir)
 if (fs.existsSync(TEMPLATE_PATH)) {
 } else {
  fs.mkdirSync(TEMPLATE_PATH)
 }
 if (dir) {
  inquirer.prompt(promptList).then(anwsers => {
  console.log(anwsers)
  })
 }
 })

program.parse(process.argv)

运行 node cli/cli.js create vue

node.js命令行教程图文详解

已经可以运行了,我们自定义一个命名替代每次都执行node

命令为:test-cli create <dir>

1、创建bin文件夹,在bin文件夹下创建index.js文件

#!/usr/bin/env node

require('../cli/cli')

2、修改package.json文件

添加bin选项

"bin": {
 "test-cli": "./bin/index.js"
 },

3、执行npm link (如果没有权限,执行sudo npm link)

4、测试

node.js命令行教程图文详解

5、发布 npm publish (如果未登录需先 npm login登录)

6、发布完毕,需npm unlink解除本地的命令映射

npm install -g XXX

总结

以上所述是小编给大家介绍的node.js命令行教程图文详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
jquery 表单下所有元素的隐藏
Jul 25 Javascript
禁止选中文字兼容IE、Chrome、FF等
Sep 04 Javascript
js使用心得分享
Jan 13 Javascript
Jquery Ajax xmlhttp请求成功问题
Feb 04 Javascript
基于jQuery实现Accordion手风琴自定义插件
Oct 13 Javascript
easy ui datagrid 从编辑框中获取值的方法
Feb 22 Javascript
ES6新特性之字符串的扩展实例分析
Apr 01 Javascript
javascript 中关于array的常用方法详解
May 05 Javascript
微信小程序与php 实现微信支付的简单实例
Jun 23 Javascript
Node.js 实现简单的无侵入式缓存框架的方法
Jul 21 Javascript
vue基于better-scroll实现左右联动滑动页面
Jun 30 Javascript
使用Vue.js和MJML创建响应式电子邮件
Mar 23 Vue.js
详解JavaScript中的坐标和距离
May 27 #Javascript
优化Vue项目编译文件大小的方法步骤
May 27 #Javascript
了解JavaScript表单操作和表单域
May 27 #Javascript
分享一个vue项目“脚手架”项目的实现步骤
May 26 #Javascript
使用JS判断页面是首次被加载还是刷新
May 26 #Javascript
Node.js 多进程处理CPU密集任务的实现
May 26 #Javascript
小程序封装路由文件和路由方法(5种全解析)
May 26 #Javascript
You might like
PHP执行批量mysql语句的解决方法
2013/05/02 PHP
PHP实现自动识别Restful API的返回内容类型
2015/02/07 PHP
Thinkphp5结合layer弹窗定制操作结果页面
2017/07/07 PHP
laravel validate 设置为中文的例子(验证提示为中文)
2019/09/29 PHP
jquery下jstree简单应用 - v1.0
2011/04/14 Javascript
js模仿php中strtotime()与date()函数实现方法
2015/08/11 Javascript
正则表达式(语法篇推荐)
2016/06/24 Javascript
JavaScript中重名的函数与对象示例详析
2017/09/28 Javascript
利用原生js实现html5小游戏之打砖块(附源码)
2018/01/03 Javascript
如何编写一个d.ts文件的步骤详解
2018/04/13 Javascript
vue+webpack实现异步加载三种用法示例详解
2018/04/24 Javascript
node上的redis调用优化示例详解
2018/10/30 Javascript
Vue中遍历数组的新方法实例详解
2019/07/21 Javascript
vue中使用WX-JSSDK的两种方法(推荐)
2020/01/18 Javascript
Python collections模块实例讲解
2014/04/07 Python
利用Python实现简单的相似图片搜索的教程
2015/04/23 Python
详解Python中最难理解的点-装饰器
2017/04/03 Python
Python模块结构与布局操作方法实例分析
2017/07/24 Python
Django中ORM表的创建和增删改查方法示例
2017/11/15 Python
Python 字符串类型列表转换成真正列表类型过程解析
2019/08/26 Python
python中取绝对值简单方法总结
2020/07/24 Python
python 提高开发效率的5个小技巧
2020/10/19 Python
python绘制高斯曲线
2021/02/19 Python
德国在线订购鲜花:Fleurop
2018/08/25 全球购物
中文专业毕业生自荐信
2013/10/28 职场文书
中医专业应届生求职信
2013/11/17 职场文书
中学生爱国演讲稿
2014/09/05 职场文书
庆祝国庆节演讲稿2014
2014/09/19 职场文书
小学生思想品德评语
2014/12/31 职场文书
委托书格式要求
2015/01/28 职场文书
初中毕业感言300字
2015/07/31 职场文书
2016年教师反腐倡廉心得体会
2016/01/13 职场文书
乡镇干部学习心得体会
2016/01/23 职场文书
pycharm代码删除恢复的方法
2021/06/26 Python
PostgreSQL13基于流复制搭建后备服务器的方法
2022/01/18 PostgreSQL
Python使用华为API为图像设置多个锚点标签
2022/04/12 Python