当前位置: 首页 > news >正文

前端架构: 脚手架命令行交互核心实现之inquirer和readline的应用教程

命令行交互核心实现

  • 核心目标:实现命令行行交互,如List
  • 命令行的交互呢比命令行的渲难度要更大,因为它涉及的技术点会会更多
  • 它涉及以下技术点
    • 键盘输入的一个监听 (这里通过 readline来实现)
    • 计算命令行窗口的尺寸
    • 清屏
    • 光标的移动
    • 输出流的静默 (我们输出的内容, 不让它去输出到当前的这个终端中)
    • 借助输入输出流,引出输入输出流的一个监听以及事件库 events
    • ansi escaped code 转义字符
  • 命行交互其实是有一定复杂度的, 在这个过程中,最重点的库和命行交互最重点库是两个 readlineinquirer

inquirer

  • inquirer 是一个命令行交互常用的库,Weekly Downloads 30,375,340 (动态数据)
  • 作为一个命令行交互的库能做到这个程度,可以说是非常的不简单,而且一直在持续的进行维护,目前已经达到9.2.15版本了
  • 安装 $ npm i -S inquirer
  • 使用示例1:input类型演示
    import inquirer from 'inquirer';
    inquirer.prompt([{type: 'input',name: 'yourName',message: 'your name:',}]).then((answers) => {console.log(answers);}).catch((error) => {if (error.isTtyError) {// Prompt couldn't be rendered in the current environment} else {// Something else went wrong}});
    
    • 这里根据文档上的框架结构
    • 通过 type, name, message 三个字段即可完成初始化创建
    • 更多,参考文档:https://www.npmjs.com/package/inquirer#question
效果实例
  • 另外,比较常用的还有
    • default 默认值字段
    • validate 字段是一个回调
      • 用于对字段的校验,只有校验返回 true的时候校验才会结束
    • transformer 字段用于处理信息展示的回调
      • 也就是这个函数内部返回的值是展示的值
      • 返回的值还是之前的 name 字段
      • 更多的像是表单中的 placeholder 仅作为展示
    • filter 字段是一个回调
      • 它会最终改变 answers 最终的结果
      • 会最终改变 name 字段
  • 其他: choice 在匹配 List 列表的时候会用到
  • 注意,prompt 方法内部接受的是一个数组,可以写多个对象来收集数据
  • 使用示例2: 多字段演示
    import inquirer from 'inquirer';inquirer.prompt([{type: 'input',name: 'yourName',message: 'your name:',default: 'Lee',validate: function(v) {return v === 'Wang'},transformer: function(v) {return 'your input name: ' + v // 仅作为展示},filter: function(v) {return v;// return v + '123' // 改变最终值}},{type: 'number', // 这种,在没有 validate 的情况下,如果输入的是非数字, 会变成 NaNname: 'num',message: 'your number',},// ...]).then((answers) => {console.log(answers); // 最终打印的是一个对象,多个字段}).catch((error) => {if (error.isTtyError) {// Prompt couldn't be rendered in the current environment} else {// Something else went wrong}});
    
    • 在示例1中已做了详细说明,这里不再赘述
效果实例
  • 使用示例3: confirm 类型演示
    import inquirer from 'inquirer';inquirer.prompt([{type: 'confirm', // 二选一功能name: 'choice',message: 'your choice:',default: false,},]).then((answers) => {console.log(answers);}).catch((error) => {if (error.isTtyError) {// Prompt couldn't be rendered in the current environment} else {// Something else went wrong}});
    
效果实例
  • 使用示例4: list 类型演示
    import inquirer from 'inquirer';inquirer.prompt([{type: 'list', // 列表单选name: 'choice',message: 'your choice:',default: 0, // 这里 default 是 下面choices 的索引choices: [{value: 1, name: 'LiLy'},{value: 2, name: 'Lucy'},{value: 3, name: 'Lee'},]},]).then((answers) => {console.log(answers);}).catch((error) => {if (error.isTtyError) {// Prompt couldn't be rendered in the current environment} else {// Something else went wrong}});
    
效果实例
  • 使用示例5: expend 类型演示
    import inquirer from 'inquirer';inquirer.prompt([{type: 'expand', // 简写选择name: 'choice',message: 'your choice:',default: 'red',choices: [{value: 'red', key: 'R'},{value: 'green', key: 'G'},{value: 'blue', key: 'B'},]},]).then((answers) => {console.log(answers);}).catch((error) => {if (error.isTtyError) {// Prompt couldn't be rendered in the current environment} else {// Something else went wrong}});
    
    • 简写选择功能,除了 Rgb 还有一个 h
    • 输入 h 回车,会得到 help 提示,列出了所有选项
    • 输入 r 回车,会得到 red, 输入 g 回车,会得到 green
效果实例
  • 使用示例6: checkbox 类型演示
    import inquirer from 'inquirer';inquirer.prompt([{type: 'checkbox', // 复选框name: 'choice',message: 'your choice:',default: 0,choices: [{value: 1, name: 'Lily'},{value: 2, name: 'Lucy'},{value: 3, name: 'Lee'},]},]).then((answers) => {console.log(answers);}).catch((error) => {if (error.isTtyError) {// Prompt couldn't be rendered in the current environment} else {// Something else went wrong}});
    
    • 这里提供 a 全选,空格键 选中,i 反选的功能
    • 默认,上下箭来选择
效果实例
  • 使用示例7: password 类型演示
    import inquirer from 'inquirer';inquirer.prompt([{type: 'password', // 密码框name: 'password',message: 'your password:',},]).then((answers) => {console.log(answers);}).catch((error) => {if (error.isTtyError) {// Prompt couldn't be rendered in the current environment} else {// Something else went wrong}});
    
效果实例
  • 使用示例8: editor 类型演示
    import inquirer from 'inquirer';inquirer.prompt([{type: 'editor', // 编辑器name: 'editor',message: 'your editor text:',},]).then((answers) => {console.log(answers);}).catch((error) => {if (error.isTtyError) {// Prompt couldn't be rendered in the current environment} else {// Something else went wrong}});
    
效果实例
  • 上面中间的这个类似 vim 的界面,会在一个缓存文件中,输入完以后,缓存文件被删除掉
  • 我们输入的结果会被保留下来,如上图
  • 这样做的好处是在文本编辑器中输入复杂的内容

readline

  • readline,是 nodejs 当中的一个内置库,主要帮我们去管理数据流的
  • 命令行当中要交互的方式,一定是需要用户提供一些输入的
  • readline 就可以很好的帮我们去一次一次的读取这个输入流
  • 注意,这个输入不仅是指我们输入一些字符,还包含我们键盘上输入的一切,如上,下,空格,回车等
  • 基本使用
    import * as readLine from 'readline';const rl = readLine.createInterface({input: process.stdin,output: process.stdout,
    });rl.question('your name: ', (answer) => {console.log(answer);rl.close(); // 关闭读取流
    })
    
  • readline 主要用途是根据传入的输入流逐行读取信息
  • 回车的时候,会认为这行输入结束,并且把所有输入的内容传递到输出流中进行展示
  • 这是readline的核心用途
  • 如果调试 readline 源码,可知,它内部会强制将函数转换为构造函数
    if (!(this instanceof Interface)) {return new Interface(input, output, completer, terminal);
    }
    
  • 接着是对 StringDecoder的判断和赋值,这个也是node的一个内置库
    if (StringDecoder === undefined) {StringDecoder = require('string_decoder').StringDecoder;
    }
    
  • 再之后,定义了一些列的参数,调用了 EventEmitter
    EventEmitter.call(this)
    
    • 这个用途是使用 this 继承 EventEmitter, this内部就会生成一些列的属性信息,如 _events, _eventsCount
    • 让当前 Interface 实例具备事件驱动的能力,因为nodejs有单线程,非阻塞IO,事件驱动的特性
    • 也就是说事件驱动,在单线程的nodejs中是非常重要的
  • 再接着,定义一些参数, 对 input 进行判断,也就是分析 input 参数
    if (input && input.input) {// ....
    }
    
  • 再往后找,看readline是如何做事件监听的
    this.output = output; // output: WriteStream 系统输出流
    this.input = input; // input: ReadStream 系统输入流// ...emitKeypressEvents(input, this) // 这里就是监听用户在终端中的键盘输入
    
    • 在 emitKeypressEvents 函数内部,会调用一个 emitKeys 的方法
    • 这里是核心, 其原理和源码不在这里进行剖析

相关文章:

前端架构: 脚手架命令行交互核心实现之inquirer和readline的应用教程

命令行交互核心实现 核心目标:实现命令行行交互,如List命令行的交互呢比命令行的渲难度要更大,因为它涉及的技术点会会更多它涉及以下技术点 键盘输入的一个监听 (这里通过 readline来实现)计算命令行窗口的尺寸清屏光标的移动输出流的静默 …...

【C++初阶】内存管理

目录 一.C语言中的动态内存管理方式 二.C中的内存管理方式 1.new/delete操作内置类型 2.new和delete操作自定义类型 3.浅识抛异常 (内存申请失败) 4.new和delete操作自定义类型 三.new和delete的实现原理 1.内置类型 2.自定义类型 一.C语…...

《PyTorch深度学习实践》第十二讲循环神经网络基础

一、RNN简介 1、RNN网络最大的特点就是可以处理序列特征,就是我们的一组动态特征。比如,我们可以通过将前三天每天的特征(是否下雨,是否有太阳等)输入到网络,从而来预测第四天的天气。 我们可以看RN…...

蓝桥杯算法题汇总

一.线性表:链式 例题:旋转链表 二.栈: 例题:行星碰撞问题 三.队列 三.数组和矩阵 例题: 四.哈希表 五.二叉树 主要方法是递归 主要考察点是遍历:前序,中序,后序遍历,层…...

【MySQL】学习多表查询和笛卡尔积 - 副本

](https://img-blog.csdnimg.cn/21dd41dce63a4f2da07b9d879ad0120b.png#pic_center) ??个人主页: ??热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ??个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-N8PeTKG6uLu4bJuM {font-family:“trebuchet ms”,…...

C++设计模式_创建型模式_工厂方法模式

目录 C设计模式_创建型模式_工厂方法模式 一、简单工厂模式 1.1 简单工厂模式引入 1.2 简单工厂模式 1.3 简单工厂模式利弊分析 1.4 简单工厂模式的UML图 二、工厂方法模式 2.1 工厂模式和简单工厂模式比较 2.2 工厂模式代码实现 2.3 工厂模式UML 三、抽象工厂模式 3.1 战斗场景…...

matlab批量替换txt文本文件的特定行的内容

1.下图所示,我想要替换第14行。 2.运行代码后,第14行已经更改为需要的内容。 clc,clear; %%----------------------需要更改的地方------------------------------------ % 设置要操作的文本文件路径,替换为你自己的文件路径 path D:\paper_…...

Qt Creator配置MSVC编译环境、调试环境

在windows上开发,一般使用Qt Creator自带mingw编译器,编译和调试都很方便,安装Qt时勾选后,自动配置完毕。 但是有时候我们需要使用MSVC的编译器,这个时候我们没法直接使用,需要配置环境才能使用&#xff0…...

Linux系统运维命令:终止监听在 TCP端口80上的所有进程(使用lsof,grep,awk组合命令, 终止监听在 TCP某个端口上的所有进程)

目 录 一、需求 二、解决方法 1、解决思路 2、命令 三、实例演示和命令解释 1、实例演示 (1)查看目前有哪些在TCP端口80监听的进程 (2)、使用命令 (3)、查看效果 2、命令解…...

开源模型应用落地-业务优化篇(七)

一、背景 在本篇学习中,我们要介绍消息中间件,它可以帮助我们将核心和辅助流程分开,让它们互相独立。同时,还要关注在使用消息中间件时需要注意的地方。并且将这种思想应用到其他实际场景中。 二、术语 2.1、消息中间件 消息中间件是一种在分布式系统中用于处理消息传递的…...

序列化-反序列化--json-xml-protoBuf

序列化和反序列化 数据在网络中传输需要按照一定的规范组成。这些规定的规范有json,xml,protobuf。 序列化 也就是说数据需要通过网络传输时,需要把数据转化为需要的传输格式,所以需要把需要传输的数据生成json或者xml或者protobuf语言格式文件&#…...

ubuntu 配置nacos开机启动

在Ubuntu系统上配置Nacos服务开机启动,可以通过创建systemd服务单元文件来实现。以下是步骤: 创建Systemd服务文件: 打开终端,使用文本编辑器(如nano或vim)新建一个服务文件: sudo nano /etc/sy…...

单节点大数据平台运维脚本

单节点的大数据集群运维脚本 vi /opt/bash/bigdata-operate-script.sh#!/bin/bashsource ~/.bashrc source /etc/profilehostnamebigdata#程序运行必要组件 important_components("kafka" "clickhouse-server" "elasticsearch" "kibana&qu…...

HTML基础知识

目录 1.初识网页 2.html:超文本标记语言 2.1排版标签 标题标签 段落标签 换行标签 水平线标签 2.2文本格式化标签 2.3媒体标签 图片标签 路径 音频标签 视频标签 2.4链接标签 2.5列表标签 2.5.1无序列表 2.5.2有序列表 2.5.3自定义列表 2.6表格…...

牛客禁用题:求阶乘

思路&#xff1a;在新类中使用全局变量进行运算&#xff0c;在主类中定义新类数组&#xff0c;通过构造函数的调用次数返回阶乘 #include <type_traits> class add{public:static int count;static int tmp;add(){countcounttmp;tmp;} }; int add::count0; int add::t…...

spring.factories的常用配置项

概述 spring.factories 实现是依赖 spring-core 包里的 SpringFactoriesLoader 类&#xff0c;这个类实现了检索 META-INF/spring.factories 文件&#xff0c;并获取指定接口的配置的功能。 Spring Factories机制提供了一种解耦容器注入的方式&#xff0c;帮助外部包&am…...

数据库-第二/三章 关系数据库和标准语言SQL【期末复习|考研复习】

前言 总结整理不易&#xff0c;希望大家点赞收藏。 给大家整理了一下计数据库系统概论中的重点概念&#xff0c;以供大家期末复习和考研复习的时候使用。 参考资料是王珊老师和萨师煊老师的数据库系统概论(第五版)。 文章目录 前言第二、三章 关系数据库和标准语言SQL2.1 关系2…...

【办公类-21-05】20240227单个word按“段落数”拆分多个Word(成果汇编 只有段落文字 1拆5)

作品展示 背景需求 前文对一套带有段落文字和表格的word进行13份拆分 【办公类-21-04】20240227单个word按“段落数”拆分多个Word&#xff08;三级育婴师操作参考题目1拆13份&#xff09;-CSDN博客文章浏览阅读293次&#xff0c;点赞8次&#xff0c;收藏3次。【办公类-21-04…...

【前端素材】推荐优质后台管理系统网页my-Task平台模板(附源码)

一、需求分析 1、系统定义 后台管理系统是一种用于管理网站、应用程序或系统的工具&#xff0c;通常由管理员使用。后台管理系统是一种用于管理和控制网站、应用程序或系统的管理界面。它通常被设计用来让网站或应用程序的管理员或运营人员管理内容、用户、数据以及其他相关功…...

Linux高负载排查最佳实践

在Linux系统中&#xff0c;经常会因为负载过高导致各种性能问题。那么如何进行排查&#xff0c;其实是有迹可循&#xff0c;而且模式固定。 本次就来分享一下&#xff0c;CPU占用过高、磁盘IO占用过高的排查方法。 还是那句话&#xff0c;以最佳实践入手&#xff0c;真传一句话…...

KubeSphere 容器平台高可用:环境搭建与可视化操作指南

Linux_k8s篇 欢迎来到Linux的世界&#xff0c;看笔记好好学多敲多打&#xff0c;每个人都是大神&#xff01; 题目&#xff1a;KubeSphere 容器平台高可用&#xff1a;环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

Nginx server_name 配置说明

Nginx 是一个高性能的反向代理和负载均衡服务器&#xff0c;其核心配置之一是 server 块中的 server_name 指令。server_name 决定了 Nginx 如何根据客户端请求的 Host 头匹配对应的虚拟主机&#xff08;Virtual Host&#xff09;。 1. 简介 Nginx 使用 server_name 指令来确定…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互

引擎版本&#xff1a; 3.8.1 语言&#xff1a; JavaScript/TypeScript、C、Java 环境&#xff1a;Window 参考&#xff1a;Java原生反射机制 您好&#xff0c;我是鹤九日&#xff01; 回顾 在上篇文章中&#xff1a;CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...

Neo4j 集群管理:原理、技术与最佳实践深度解析

Neo4j 的集群技术是其企业级高可用性、可扩展性和容错能力的核心。通过深入分析官方文档,本文将系统阐述其集群管理的核心原理、关键技术、实用技巧和行业最佳实践。 Neo4j 的 Causal Clustering 架构提供了一个强大而灵活的基石,用于构建高可用、可扩展且一致的图数据库服务…...

什么?连接服务器也能可视化显示界面?:基于X11 Forwarding + CentOS + MobaXterm实战指南

文章目录 什么是X11?环境准备实战步骤1️⃣ 服务器端配置(CentOS)2️⃣ 客户端配置(MobaXterm)3️⃣ 验证X11 Forwarding4️⃣ 运行自定义GUI程序(Python示例)5️⃣ 成功效果![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/55aefaea8a9f477e86d065227851fe3d.pn…...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

Web 架构之 CDN 加速原理与落地实践

文章目录 一、思维导图二、正文内容&#xff08;一&#xff09;CDN 基础概念1. 定义2. 组成部分 &#xff08;二&#xff09;CDN 加速原理1. 请求路由2. 内容缓存3. 内容更新 &#xff08;三&#xff09;CDN 落地实践1. 选择 CDN 服务商2. 配置 CDN3. 集成到 Web 架构 &#xf…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

【Java学习笔记】BigInteger 和 BigDecimal 类

BigInteger 和 BigDecimal 类 二者共有的常见方法 方法功能add加subtract减multiply乘divide除 注意点&#xff1a;传参类型必须是类对象 一、BigInteger 1. 作用&#xff1a;适合保存比较大的整型数 2. 使用说明 创建BigInteger对象 传入字符串 3. 代码示例 import j…...