当前位置: 首页 > 后端技术 > Node.js

node.js命令行教程

时间:2023-04-03 18:40:54 Node.js

node命令行教程本文首先介绍原生node.js实现命令行交互,了解原生api,然后通过commander.js和inquirer.js实现一个完整的交互命令行工具.项目地址进程(process)进程对象是一个全局变量,提供信息,控制当前node.js进程。由于是全局变量,所以不需要在文件中导入。几个apiprocess.argvprocess.cwd()process.stdinprocess.stdoutprocess.stdin.resume()process.argvprocess.argv属性返回一个数组。数组的第一个值为process.execPath,第二个为正在执行的JavaScript的文件路径,其余参数为其他命令参数,这是我们自定义命令的关键。示例Createnewargv.js//argv.jsconsole.log(process.argv)executenodecommandnodeargv.jsnodeargv.js--namezhu##output['/usr/local/bin/node',##executecurrent脚本的Node二进制文件的绝对路径'/Users/zhuhuilong/Node/Book/argv.js',##文件的绝对路径'--name',##其他参数'zhu']接收自定义命令Process输出的参数//argv.jsconsole.log(process.argv)letargvs=process.argvletparam=argvs.splice(2)if(param[0]&¶m[0]=='--name'){if(param[1]){console.log(`hello${param[1]}`)}else{console.log('Pleaseentername')}}runargv.jsnodeargv.js--namezhu##输出['/usr/local/bin/node','/Users/zhuhuilong/Node/Book/argv.js','--name','zhu']hellozhuparam['--name','zhu']process.stdin和process.stdoutprocess.stdin(标准输入)process.stdin属性返回连接到stdin(fd0)的流。它是一个net.Socket流(又名双工),除非fd0指向一个文件,在这种情况下它是一个可读流。process.stdout(标准输出)process.stdout属性返回连接到stdout(fd1)的流。它是一个net.Socket流(又名双工),除非fd1指向一个文件,在这种情况下它是一个可写流。process.stdin.resume()指向标准输入流(stdin)的可读流。标准输入流默认是暂停的,所以必须调用process.stdin.resume()来恢复(resume)接收。作为一个流,process.stdin可以在传统模式下使用。为了兼容nodev0.10之前的版本。在喜欢使用标准输入的旧模式中,必须调用process.stdin.resume()。请注意,如果调用process.stdin.resume(),标准输入将恢复为旧模式。通俗地说,控制台就是在不退出进程的情况下等待我们的输入,进行输入输出交互。newinputout.js//inputout.jsprocess.stdin.setEncoding('utf8')letargvs=process.argvletparam=argvs.splice(2)if(param[0]&¶m[0]=='--name'){if(param[1]){console.log(`hello${param[1]}`)}else{process.stdout.write(`Pleaseentername:`)process.stdin.resume()进程。stdin.on('data',chunk=>{if(!!chunk.replace(/[\r\n]/g,'')){process.stdout.write(`你输入的名字是:${chunk}`)process.stdin.emit('end')}else{process.stdout.write(`Pleaseentername:`)}})}}process.stdin.on('end',()=>{process.stdout.write('End\n')})>executenodeinputout.js--nameRemark在新版本node模式下,process.stdin.on("readable",()=>{})可以改为使用process.stdin.resume()恢复输入流接收。示例:process.stdin.on("readable",()=>{varchunk=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受RubyCommander启发的node.js命令行界面的完整解决方案。commander.jsprogram.version()声明版本的API概述constprogram=require('commander')constpkg=require('../package.json')program.version(pkg.version)Options使用.option解析()方法定义了指挥官的选项选项,也可以作为选项的文件。varprogram=require('指挥官');program.version('0.1.0').option('-p,--peppers','Addpeppers').option('-P,--pineapple','Addpineapple').option('-b,--bbq-sauce','添加烧烤酱').option('-c,--cheese[type]','添加指定类型的奶酪[marble]','marble').parse(process.argv);console.log('youorderedapizzawith:');if(program.peppers)console.log('-peppers');if(program.pineapple)console.log('-pineapple');if(program.bbqSauce)console.log('-bbq');console.log('-%scheese',program.cheese);添加自定义命令program.command()varprogram=require('commander');program.command('rm

')//<>必需参数,如果是[],则为可选参数.option('-r,--recursive','递归删除').action(function(dir,cmd){console.log('remove'+dir+(cmd.recursive?'recursively':''))})program.parse(process.argv)//command()变量参数/**命令命令只有最后一个参数是可变的而不是固定的。要使参数变量可变,您必须将...附加到参数名称。**/program.version('0.1.0').command('rmdir[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()定义命令的回调函数varprogram=require("commander");program.command("rm").option("-r,--recursive","Removerecursively").option("-f,--force","removeforce").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.jsInquirer.js是使用NodeJs制作的通用交互式命令行用户界面的集合。具有通用的控制台交互。由于互动问题的类型不同,提问者为每个问题提供了很多参数:type:表示问题的类型,包括:input、confirm、list、rawlist、expand、checkbox、password、editor;name:存储当前问题答案的变量;message:问题的描述;默认值:默认值;choices:列出选项,在某些类型下可用,并包含一个分隔符(separator);validate:验证用户的回答;filter:过滤用户的回答处理,返回处理后的值;transformer:处理用户答案的??显示效果(如:修改答案的字体或背景颜色),但不会影响最终答案的内容;when:根据上一题的答案判断当前答案是否需要回答该题;pageSize:修改某些类型下的渲染行数;prefix:修改消息的默认前缀;后缀:修改消息的默认后缀。创建cli.jsconstprogram=require('commander')constinquirer=require('inquirer')constfs=require('fs')constpath=require('path')constpkg=require('../package.json')constCWD=process.cwd()constpromptList=[{type:'list',message:'Pleasechooseatemplate',name:'template',choices:['vue','angular','webpack-m-pages'],filter:function(val){returnval.toLowerCase()}}]program.version(pkg.version).command('create').description('创建项目模板').action(function(dir,cmd){constTEMPLATE_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)runnodecli/cli.jscreatevue准备运行,我们自定义一个名字来替换每一个每次执行node命令:test-clicreate1。创建bin文件夹,并在bin文件夹下创建index.js文件#!/usr/bin/envnoderequire('../cli/cli')2.修改package.json文件,增加bin选项"bin":{"test-cli":"./bin/index.js"},3.执行npm链接(如果没有权限,执行sudonpmlink)4、测试5.发布npmpublish(如果没有登录,需要先用npmlogin登录)6.发布后,需要发布本地命令映射npminstall-gXXX和npm取消链接