首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【nodejs脚手架开发】交互处理-Inquirer.js篇

【nodejs脚手架开发】交互处理-Inquirer.js篇

原创
作者头像
hasaki
修改2021-08-30 21:49:42
1.8K5
修改2021-08-30 21:49:42
举报
文章被收录于专栏:脚手架开发脚手架开发

【nodejs脚手架开发】交互处理-Inquirer.js篇

上一篇 文章讲解了nodejs开发的第一步,命令处理,命令处理的短板是无法处理复杂的选项,而inquier.js解决了这一问题。这篇文章继续介绍脚手架中的交互处理。

什么是交互?

说交互可能会引发一些歧义,我个人习惯将交互理解为客服,我们在购物的时候,客服会向你问一系列的问题,比如:

  • 你的性别是?
  • 你的身高是?
  • 请您选一个衣服颜色(红,黄,白,绿, 黑)
  • 体恤还是夹克?
  • 。。。。

等等问题,然后会根据你的需求,向你推荐合适的衣服。而Inquirer.js在命令行开发中则承担了这一角色,让我们根据使用者的需要,来做相应的处理。比如vue-cli中的vue create命令,在创建项目时会问以下问题:

  • 选择预设:Please pick a preset
  • 选择特性:Check the features needed for your project
  • 选择vue版本:Choose a version of Vue.js that you want to start the project with
  • 选择css预处理器:Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default)
  • 选择eslint校验时机:Pick additional lint features
  • 。。。。

什么是Inquirer.js?

如图,inquirer.js主要包括问题的类型和问题的处理两个部分,问题的类型包含:

  • input:可以理解为填空题,需要用户输入
  • confirm: 由用户通过快捷键y/n选择是/否,判断题
  • list: 无序列表单选题
  • rawlist: 有序列表单选题
  • expand: 可以通过key定义快捷选择,如A, B, C, D 选择题
  • checkbox: 多选题
  • pasword: 密码输入,输入时掩码代替显示
  • editor: 通过vim编辑器输入

问题的处理比较简单也比较丰富,主要包括以下属性:

  • message: 问题的描述
  • name: 问题答案值的属性名,可以理解为form表单prop
  • choices: 选项列表
  • pagesize: choices过多时每页显示的个数
  • surfix和prefix:问题描述的前后缀
  • default: 默认值
  • when: 问题回答后的回调函数,可以处理问题的依赖关系
  • filter: 对回答进行过滤
  • validate: 对回答进行验证
  • transformer: 对回答进行格式化显示,但不会改变回答的值

讲了这么多概念,如果我们要做一个选择题,写法如下:

const inquirer = require('inquirer')

const propmtList = [{
  type: 'list',
  message: 'Please pick a preset',
  name: 'preset',
  choices: [
    "Default ([Vue 2] babel, eslint)",
    "Default (Vue 3 Preview) ([Vue 3] babel, eslint)",
    "Manually select features"
  ],
}]

inquirer.prompt(propmtList);

运行效果如下:

实现vue create效果

const program = require('commander');
const inquirer = require('inquirer')

const propmtList = [{
  type: 'list',
  message: 'Please pick a preset',
  name: 'preset',
  choices: [
    "Default ([Vue 2] babel, eslint)",
    "Default (Vue 3 Preview) ([Vue 3] babel, eslint)",
    "Manually select features"
  ],
}, {
  type: 'checkbox',
  message: 'Check the features needed for your project',
  name: 'features',
  choices: [{
    name: 'Choose Vue version',
    checked: true,
  }, {
    name: 'Babel',
    checked: true,
  }, {
    name: 'TypeScript',
  }, {
    name: 'Progressive Web App (PWA) Support',
  }, {
    name: 'Router',
  }, {
    name: 'Vuex',
  }, {
    name: 'CSS Pre-processors',
  }, {
    name: 'Linter / Formatter',
    checked: true,
  }, {
    name: 'Unit Testing',
    checked: true,
  }, {
    name: 'E2E Testing',
    checked: true,
  }],
  pageSize: 10,
}, {
  type: 'list',
  message: 'Choose a version of Vue.js that you want to start the project with',
  name: 'version',
  choices: [
    "2.x",
    "3.x (Preview)"
  ],
}, {
  type: 'confirm',
  message: 'Use history mode for router? (Requires proper server setup for index fallback in production)',
  name: 'routerMode',
  default: ''
}, {
  type: 'list',
  name: 'cssProcessor',
  message: 'Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default)',
  choices: [
    "Sass/SCSS (with dart-sass)",
    "Sass/SCSS (with node-sass)",
    "Less",
    "Stylus",
  ]
}, {
  type: 'checkbox',
  name: 'lint',
  message: 'Pick additional lint features',
  choices: [
    "Lint on save",
    "Lint and fix on commit",
  ]
}, {
  type: 'list',
  name: 'where',
  message: 'Where do you prefer placing config for Babel, ESLint, etc.?',
  choices: [
    "In dedicated config files",
    "In package.json",
  ]
}, {
  type: 'confirm',
  name: 'save',
  message: 'Save this as a preset for future projects? ',
}];

program.usage('Usage: create [options] <app-name>')
  .argument('[app-name]')
  .showHelpAfterError()
  .description('create a new project powered by vue-cli-service')
  .option('-p, --preset <presetName>', 'Skip prompts and use saved or remote preset')
  .option('-d, --default', 'Skip prompts and use default preset')
  .option('-i, --inlinePreset <json>', 'Skip prompts and use inline JSON string as preset')
  .option('-m, --packageManager <command>', 'Use specified npm client when installing dependencies')
  .option('-r, --registry <url>', 'Use specified npm registry when installing dependencies (only for npm)')
  .option('-g, --git [message]', 'Force git initialization with initial commit message')
  .option('-n, --no-git', 'Skip git initialization')
  .option('--merge', 'Merge target directory if it exists')
  .option('-c, --clone', 'Use git clone when fetching remote preset')
  .option('-x, --proxy <proxyUrl>', 'Use specified proxy when creating project')
  .option('-b, --bare', 'Scaffold project without beginner instructions')
  .option('--skipGetStarted', 'Merge target directory if it exists')
  .action((name, options, command) => {
    if (!name) {
      program.help();
      return;
    } 
    inquirer.prompt(propmtList).then(answer => {
      console.log(answer);
    });
  })
  .parse();

运行效果

node ./bin/my-cli.js create

没有输入工程名称时自动答应帮助信息:

node ./bin/my-cli.js create hello

选择预设

选择特性

选择vue版本

是否使用history模式

选择css预处理器

选择eslint执行时机

选择babel config的存储位置

是否存为预设

打印用户的所有选择

总结

inquirer.js的实现简洁而优雅,文档清晰明了,对于脚手架开发的交互处理简单方便,定义了丰富的问题类型,和问题处理方法,简单易学,结合模拟实现vue-cli实现,有利于了解vue-cli是如何工作的。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 【nodejs脚手架开发】交互处理-Inquirer.js篇
    • 什么是交互?
      • 什么是Inquirer.js?
        • 实现vue create效果
          • 运行效果
            • 总结
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档