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

这篇具有很好参考价值的文章主要介绍了前端架构: 脚手架命令行交互核心实现之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
inquirer文档,FE Architecture,前端,前端架构,脚手架
效果实例
  • 另外,比较常用的还有
    • 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 的情况下,如果输入的是非数字, 会变成 NaN
    	  	name: '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中已做了详细说明,这里不再赘述
inquirer文档,FE Architecture,前端,前端架构,脚手架
效果实例
  • 使用示例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
        }
      });
    
inquirer文档,FE Architecture,前端,前端架构,脚手架
效果实例
  • 使用示例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
        }
      });
    
inquirer文档,FE Architecture,前端,前端架构,脚手架inquirer文档,FE Architecture,前端,前端架构,脚手架
效果实例
  • 使用示例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
inquirer文档,FE Architecture,前端,前端架构,脚手架inquirer文档,FE Architecture,前端,前端架构,脚手架
效果实例
  • 使用示例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 反选的功能
    • 默认,上下箭来选择
inquirer文档,FE Architecture,前端,前端架构,脚手架inquirer文档,FE Architecture,前端,前端架构,脚手架
效果实例
  • 使用示例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
        }
      });
    
inquirer文档,FE Architecture,前端,前端架构,脚手架
效果实例
  • 使用示例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
        }
      });
    
inquirer文档,FE Architecture,前端,前端架构,脚手架inquirer文档,FE Architecture,前端,前端架构,脚手架inquirer文档,FE Architecture,前端,前端架构,脚手架
效果实例
  • 上面中间的这个类似 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(); // 关闭读取流
    })
    
inquirer文档,FE Architecture,前端,前端架构,脚手架
  • 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 的方法
    • 这里是核心, 其原理和源码不在这里进行剖析

文章来源地址https://www.toymoban.com/news/detail-856231.html

到了这里,关于前端架构: 脚手架命令行交互核心实现之inquirer和readline的应用教程的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 前端架构: 脚手架之Chalk和Chalk-CLI使用教程

    Chalk Chalk 是粉笔的意思, 它想表达的是,给我们的命令行中的文本添加颜色类似彩色粉笔的功能 在官方文档当中,它的 Highlights 核心特性 它的性能很高,没有三方依赖 它能够支持256以及真彩色的实现 也就是说这个库可以让你自己去定义它的色彩 并不是说命令行中当中的25

    2024年02月21日
    浏览(62)
  • 实现一个简单的前端脚手架

    前端脚手架概念 实现前端脚手架 随着前端工程化的概念越来越深入人心,脚手架应运而生。简单来说,「前端脚手架」就是指通过选择几个选项快速搭建项目基础代码的工具 前端脚手架可帮我们做什么? 可以帮助我们快速生成项目的基础代码 脚手架工具的项目模板经过了

    2024年02月03日
    浏览(46)
  • springcloud-alibaba五大核心组件-后端开发工程(脚手架)搭建

    Gitee仓库地址 点我 服务注册与发现: nacos 配置中心: nacos 服务远程调用: openfeign 微服务网关: gateway 服务限流降级熔断等: sentinel 实现的功能demo openfeign服务远程调用 sentinel限流测试 gateway网关调用2个微服务 nacos的服务注册与发现 软件架构(环境) jdk: 1.8 maven: 3.5.2 nacos: 注册中心

    2024年02月05日
    浏览(55)
  • 和chatgpt学架构01-搭建项目脚手架

    今年3月份以来,chatgpt就热度不减。有了这种聊天机器人,就可以很方便的帮助我们提高。无论是我们独立创业还是做项目外包,拥有一套自己可以把握的脚手架还是必备的能力。 过去如果靠自己摸索,组装这么一套脚手架还是费事费力的。一个是涉及技术比较多,既要架构

    2024年02月16日
    浏览(53)
  • 处理解决运行前端脚手架工程报错: ‘vue-cli-service‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。附带 Linux

    目录 一、场景介绍 二、处理方式         1、 如果 package.json 配置没有 vue-cli-server 那么就安装它即可,注意安装完毕需重启编辑器启动项目,避免依赖添加不生效问题         2、如果 package.json 配置有 vue-cli-server 或者安装了还是没好,可以看看 node_modules 工程模块是否存

    2024年02月22日
    浏览(68)
  • 前端如何搭建脚手架并在本地运行

    在开始搭建前,确保本机安装了node,为避免奇奇怪怪的问题 建议node版本16以上 使用过vue ,react,angular的同学都知道 ,应该对脚手架有一定的理解,比如vue-cli的 vue create myApp ,其中vue 就是vue-cli声明的一个命令,下来我们创建一个项目并声明自己的命令。 创建一个空的文件夹

    2024年02月20日
    浏览(45)
  • Vue2向Vue3过度核心技术工程化开发和脚手架

    1.1 开发Vue的两种方式 核心包传统开发模式:基于html / css / js 文件,直接引入核心包,开发 Vue。 工程化开发模式:基于构建工具(例如:webpack)的环境中开发Vue。 工程化开发模式优点: 提高编码效率,比如使用JS新语法、Less/Sass、Typescript等通过webpack都可以编译成浏览器识

    2024年02月11日
    浏览(55)
  • Vue的架构以及基于脚手架环境开发vue项目

    M:model 模型层(业务逻辑层),主要包含 JS 代码,用于管理业务逻辑的实现。 V:View 视图层,主要包括 HTML / CSS代码,用于管理 UI 的展示。 VM:viewModel (视图模型层),用于将data与视图层的 DOM 进行动态绑定。 基于脚手架环境开发Vue项目 制作web 从小作坊状态转向工程化开

    2024年02月01日
    浏览(54)
  • 【前端】Vue2 脚手架模块化开发 -快速入门

    🎄欢迎来到@边境矢梦°的csdn博文🎄  🎄本文主要梳理Vue2 脚手架模块化开发 🎄 🌈我是边境矢梦°,一个正在为秋招和算法竞赛做准备的学生🌈 🎆喜欢的朋友可以关注一下 🫰🫰🫰 ,下次更新不迷路🎆 Ps: 月亮越亮说明知识点越重要 (重要性或者难度越大)🌑🌒🌓🌔🌕

    2024年02月10日
    浏览(82)
  • 新鲜出炉的 MVVM 脚手架 —— KtArmor-MVVM,面试安卓系统架构

    } 通过 @BindViewModel 注解viewModel 变量,KtArmor-MVVM 通过 反射 ,自动创建 LoginViewModel 实例, 并赋值给 viewModel 变量。直接使用即可! @BaseUrl(API.BASE_URL) // 看这里!! interface ApiService { @POST(API.LOGIN) suspend fun login(@Query(“username”) username: String, @Query(“password”) password: String): BaseRe

    2024年04月10日
    浏览(47)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包