手机版

教你如何使用nodejs编写cli命令行

时间:2021-08-29 来源:互联网 编辑:宝哥软件园 浏览:

在前端的日常开发中,你会遇到各种clis,比如一行命令打包的webpack、一行命令生成的vue-cli、react project创建的create-react-app等。这些工具极大地方便了我们的日常工作,让电脑自己做繁琐的工作,可以为我们学习、交流、开发和访问steam节省大量时间。

但是有时候我们找不到适合一些特殊需求的cli工具。例如,您的项目非常大,您必须经历创建目录的过程。vue文件-更新vue路由器的路由表。即使使用快捷键来创建目录文件,它也会比您的一行命令更快,尤其是当路由目录深度嵌套并且的初始化模板。vue文件很复杂。

那么,为什么不为你的项目编写一个cli呢?只是做这些乏味的工作?

0x1你好世界

nodejs的cli本质上是运行节点脚本。基本上,每个前端er都会:

//index . jsconsole . log(' hello world '),然后从命令行调用

node index.js##的输出:hello world可以做得更逼真。让我们将脚本名称添加到package.json中的scripts字段:

{ ' scripts ' : { ' hello ' : ' node index . js ' } }然后命令行调用:

NPM run hello

然而,当你看到这个的时候,你肯定会说webpack和vue-cli都有名字!什么vue-cli init app,webpack -p,多漂亮,看看这个命令行,node index.js,还有npm run你好,谁不会,很难看,恐怕不是水的文章。差评!

别担心,先生们,我们来谈谈如何给这个节点脚本命名。

0x2名称

我们先把这个cli命名为hello-cli,也就是我们可以在命令行中输入hello-cli,然后它会打印一句hello world,无节点无npm,也就是:

在这里,我们需要做几个步骤:

1.index.js文件的顶部声明了执行环境:

//index.js#!/usr/bin/envnode console . log(' hello world ')add #!/usr/bin/env节点或#!/usr/bin/node,它告诉系统下面的脚本由nodejs执行。当然这个系统不包括windows,因为windows下有JScript的历史遗迹,会让你的脚本无法运行。

#!/usr/bin/env node的意思是让系统自己找到节点的执行器。

#!/usr/bin/node是指明确告诉系统节点的可执行程序在/usr/bin/node的路径中。

2.添加package.json的bin字段

您可以在index.js的当前目录中执行npm init来创建一个package.json,然后在package.json中添加一个bin字段:

{'name' :' hello-test ',' version' :' 1.0.0 ',' bin ' : { ' hello-cli ' : ' index . js ' } }这个命令行的名字写在bin字段,也就是hello-CLI,它告诉npm当然,你想写的命令行的名字是你的自由,比如:

3.在当前的package.json目录中,打开命令行工具,执行npm链接,并在npm全局目录中留下当前代码的快捷方式。

当npm检测到package.json中有bin字段时,它会在全局npm包目录中同时生成一个可执行文件:

当我们在系统命令行上直接执行hello-cli时,实际上是在这里执行脚本。

由于npm在安装节点时将此目录配置为系统变量环境,所以在执行命令时,系统会先查找系统命令和系统变量,然后在变量环境中查找命令名,找到此目录后再查找与命令名匹配的可执行文件,然后直接执行。vue-cli或webpack-cli都是以这种方式执行的。

这样,您的第一个cli脚本就成功安装了。您可以直接在命令行中键入cli名称,并查看结果输出。

此外,如果您只想在项目中执行cli脚本,则需要在项目中创建新目录并重复上述操作。在第三步中,使用npm i -D文件:将脚本cli目录路径作为项目依赖项安装到node_modules中,而不是单击进入全局环境。如果安装成功,您将在project package.json中再看到一个。然后在node_modules中将有一个. bin目录,您的可执行文件将存储在其中。

建议使用npm i -D文件file:xxx进行本地安装,这样会在package.json中留下一条记录,让其他伙伴看到。自然,最好将您的脚本放在项目目录中。

当然,对于以这种方式安装的cli脚本,脚本命令必须在项目的package.json的scripts字段上声明,然后由npm run执行。

哦?如果你像这样使用它,你会回到最初的npm运行你好。

是的,但是有质的区别。使用node index.js既简单又灵活,但它严重依赖脚本路径。一旦目录结构改变,脚本中编写的命令将被改变一次;但是,安装npm后,本地cli脚本被拉入node_modules,目录结构的变化对其影响不大。其次,不利于分享和发布。如果你想发布你的cli脚本,它有一个好听又响亮的名字,这比告诉用户如何找到你的脚本路径,然后用description文档中的node执行要好一万倍,不是吗?

这里还为我们提供了一个cli开发流程:

通过node index.js可以看到初始开发的效果.测试时,您可以通过npm链接进行安装和测试。发出0x3参数读取:process.argv

名字在那里,输出也在那里。让我们看看我们和那些著名的cli工具在形式上有什么不同?顺便说一下,人们可以支持不同的参数选项,并根据不同的输入产生不同的结果。

好吧,让我们给这个cli添加一个函数。既然叫hello-cli,就不能只说hello world。无论何时你遇到某人,你都必须打招呼:

hello-CLI older # # Output hello older虽然这个功能很简单,但至少达到了“根据不同的输入产生不同的结果”的效果。

命令行上的参数可以通过变量process获得,变量process是一个全局对象而不是包,不需要通过require引入。通过process对象,我们可以得到当前脚本执行环境等一系列信息,包括命令行的输入,存储在属性process.argv中我们可以打印出来:

//index . js console . log(process . argv);打印结果:

可以看到argv是一个数组,前两位是固定的,分别是节点程序的路径和存储脚本的位置,额外的输入只从第三位开始。那么实现以上功能就很简单了,只需读取argv数组的第三位并输出即可。

//index . jsconsole . log(` hello $ { process . argv[2]| | ' world ' } `)NPM社区也有一些优秀的命令行参数解析包,比如yargs,tj的tj commander.js等等

如果要使用复杂的参数或命令,最好使用第三方包,因为手写分析太耗费精力。

0x4子进程

现在,您可以自由编写自己的cli脚本。

如果你想写一个项目并自动推送到git的cli,或者从git仓库中自动拉取项目启动模板,那么你需要通过node的child_process模块打开子流程,在子流程中调用git命令:

//test . jsconst child _ process=require(' child _ process ');让subProcess=child _ process . exec(' git version ',function(err,stdout){ if(err)console . log(err);console . log(stdout);subprocess . kill()});这里不仅可以执行git命令,还可以执行系统命令和其他cli命令。尤其是系统命令,使用系统命令操作文件目录比fs更有效率。

社区里也有一些不错的套餐,比如阮一峰老师推荐的shelljs

0x5美化输出

如果你不希望自己的cli“硬核”,想要更人性化,比如提供一些友好的输入和提示,在输出中加入一些颜色来区分关键点,写一个简单的进度条等等,那么就需要美化输出。

除了颜色部分,不使用第三方包实现起来非常繁琐复杂,可以尝试自己写其他功能。

颜色部分使用了第三方包装颜色,这里就不做演示了。

其他的由nodejs自己的readline模块实现。

//index . jsconst readline=require(' readline ');const UnloadChar=“-”;const loadedChar='=const rl=readline . create interface({ input : process . stdin,output : process . stdout });问题(‘你想和谁打招呼?’,答案={ let I=0;让time=setInterval(()={ if(i10){ clearInterval(time);readline . cursorto(process . stdout,0,0);readline . clearscreendown(process . stdout);console . log(` hello $ { answer } `);process . exit(0)return } readline . cursorto(process . stdout,0,1);readline . clearscreendown(process . stdout);renderProgress('打招呼,我);i },200);});函数renderProgress(文本,步骤){ const PERCENT=Math.round(步骤* 10);const COUNT=2;const unloadStr=新数组(COUNT*(10步))。填充(卸载字符)。join(' ');const loadedStr=新数组(COUNT*(步骤))。填充(加载的字符)。join(' ');流程。标准输出。write(`$ { text } :[$ { load str } $ { unload str } | $ { percent } %]`)}首先,通过readline.createInterface方法创建一个接口类,该方法有一个方法。下面的问题,并使用此方法在命令行上抛出一个问题。一旦用户完成输入并按回车键,回拨功能将被触发。

然后我们在回调函数中编写一个计时器,假装我们正在处理一些事务。

使用readline.cursorTo方法更改命令行上的光标位置。

readline . cursorto(process . stdout,0,0);移动到第1列第1行,

readline . cursorto(process . stdout,0,1);是的,移到第1列第2行。

readline.clearScreenDown的方法是让命令行清除从当前行到最后一行结束的两行之间的所有内容。

RenderProgress是一个自身封装的方法,它通过process.stdout.write方法向命令行输出一个看起来像进度条的字符串。

所以在计时器中,当计数小于10时,我们将光标移动到第一行,然后清除所有输出并输出进度条字符串;当计数大于10时,我们关闭计时器,清除输出并打印结果。

最后,别忘了关闭流程。您可以使用。方法关闭readline进程,也可以直接调用process.exit退出。

绘图的思想和用canvas绘制动画是一样的,只是canvas清除了canvas,而这里的命令行通过readline.clearScreenDown清除了输出

这样就写出了一个简单、人性化的带有一点进度条动画的命令行cli工具,你可以用你的想象力写一些更有趣的效果。

毕竟在我们的前端,可以用浏览器写动画,不用浏览器也可以写动画。

以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。

版权声明:教你如何使用nodejs编写cli命令行是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。