inquirer用法

const inquirer = require('inquirer');
inquirer
  .prompt([
    {
      type: 'input',
      name: 'youName',
      message: 'your name',
      validate: function(v) {
        return typeof v === 'string';
      },
      transformer: function(v) {
        return v + `(input your name)`;
      },
      filter: function(v) {
        return `name[${v}]`
      }
    },
    {
      type: 'number',
      name: 'youNumber',
      message: 'your number'
    },
    {
      type: 'password',
      name: 'password',
      message: 'your password'
    },
    {
      type: 'confirm',
      name: 'yourConfirm',
      message: 'your confirm',
      default: false
    },
    {
      type: 'confirm',
      name: 'yourConfirm',
      message: 'your confirm'
    },
    {
      type: 'list',
      name: 'yourChoice',
      message: 'your choice list',
      default: 0,
      choices: [
        { value: 1, name: 'sam' },
        { value: 2, name: 'shuangyue' },
        { value: 3, name: 'zhangxuan' }
      ]
    },
    {
      type: 'rawlist',
      name: 'yourChoice',
      message: 'your choice list',
      default: 0,
      choices: [
        { value: 1, name: 'sam' },
        { value: 2, name: 'shuangyue' },
        { value: 3, name: 'zhangxuan' }
      ]
    },
    {
      type: 'expand',
      name: 'expand',
      message: 'your expand',
      default: 'red',
      choices: [
        { key: 'R', value: 'red' },
        { key: 'G', value: 'green' },
        { key: 'B', value: 'blue' }
      ]
    },
    {
      type: 'checkbox',
      name: 'checkbox',
      message: 'your checkbox',
      default: 0,
      choices: [
        { value: 1, name: 'sam' },
        { value: 2, name: 'shuangyue' },
        { value: 3, name: 'zhangxuan' }
      ]
    },
    {
      type: 'editor',
      name: 'editor',
      message: 'your editor'
    },
  ])
  .then(answers => {
    console.log(answers)
  })
  .catch(error => {
    if(error.isTtyError) {
      // Prompt couldn't be rendered in the current environment
    } else {
      // Something else when wrong
    }
  });

windows修改域名映射关系

找到C:\Windows\System32\drivers\etc目录 打开hosts文件修改映射关系 127.0.0.1 www.why.com 浏览器输入www.why.com:7001/project/template

手写readline核心实现

function stepread(cb) {

  function onKeypress(s) {
    output.write(s);
    line += s;
    switch (s) {
      case '\r':
        input.pause();
        cb(line);
        break;
    }
  }

  const input = process.stdin;
  const output = process.stdout;
  let line = '';

  emitKeypressEvents(input);

  input.on('keypress', onKeypress);

  input.setRawMode(true);
  input.resume();
}

function emitKeypressEvents(input) {
  function onData(chunk) {
    g.next(chunk.toString());
  }

  const g = emitKeys(input);
  g.next();

  input.on('data', onData);
}

function* emitKeys(input) {
  while (true) {
    let ch = yield;
    input.emit('keypress', ch);
  }
}

stepread(function (answer) {
  console.log('answer:' + answer);
});

ansi-escape

ANSI escape sequences are a standard for in-band signaling to control the cursor location, color, and other options on video text terminals and terminal emulators.

console.log(`\x1B[93m\x1B[4m%s\x1B[0m`, 'your name');

rxjs

RxJSReactiveX编程理念的JavaScript版本。ReactiveX来自微软,它是一种针对异步数据流的编程。简单来说,它将一切数据,包括HTTP请求,DOM事件或者普通数据等包装成流的形式,然后用强大丰富的操作符对流进行处理,使你能以同步编程的方式处理异步数据,并组合不同的操作符来轻松优雅的实现你所需要的功能。 类似Promise

const { range } = require('rxjs');
const { map, filter } = require('rxjs/operators');

const pipe = range(1, 200).pipe(
  filter(x => x % 2 === 1),
  map(x => x + x),
  filter(x => x % 3 === 0),
  filter(x => x % 6 === 0),
  filter(x => x % 9 === 0)
)

pipe.subscribe(x => console.log(x));

手写命令行交互列表

const EventEmitter = require('events');
const MuteStream = require('mute-stream');
const readline = require('readline');
const {fromEvent} = require('rxjs');
var cliCursor = require('cli-cursor');
const ansiEscapes = require('ansi-escapes');

const option = {
  type: 'list',
  name: 'userList',
  message: '请选择姓名',
  choices: [
    { value: 'sam', name: 'sam'},
    { value: 'sy', name: 'shuangyue'},
    { value: 'zx', name: 'zhangxuan'}
  ]
}


class List extends EventEmitter {
  constructor(list) {
    super();

    this.type = list.type;
    this.name = list.name;
    this.message = list.message;
    this.choices = list.choices;

    this.input = process.stdin;
    const ms = new MuteStream();
    ms.pipe(process.stdout);
    this.output = ms;

    this.rl = readline.createInterface({
      input: this.input,
      output: this.output
    })

    this.selected = 0;
    this.height = 0;

    this.keypress = fromEvent(this.rl.input, 'keypress').forEach(this.onkeypress);

    this.haveSelected = false;

  }

  onkeypress= (keys) => {
    const key = keys[1];
    switch (key.name) {
      case 'down':
        if (this.selected === this.choices.length - 1) {
          this.selected = 0;
        } else {
          this.selected++;
        }
        this.render();
        break;
      case 'up':
        if (this.selected === 0) {
          this.selected = this.choices.length - 1;
        } else {
          this.selected--;
        }
        this.render();
        break;
      case 'return':
        this.haveSelected = true;
        this.render();
        this.close();
        // 派发给程序开发者的
        this.emit('exit', this.choices[this.selected]);
        break;
      default:
        break;
    }
  }

  render() {
    this.output.unmute();
    this.clean();
    this.output.write(this.getContent());
    this.output.mute();
  }

  getContent() {
    if (!this.haveSelected) {
      let content = '\x1B[32m?\x1B[39m \x1B[1m' + this.message + '\x1B[22m\x1B[0m \x1B[0m\x1B[2m(Use arrow keys)\x1B[22m\n';
      this.choices.forEach((choice, index) => {
        if (index === this.selected) {
          if (index === this.choices.length - 1) {
            content += '\x1B[36m> ' + choice.name + '\x1B[39m\n';
          } else {
            content += '\x1B[36m> ' + choice.name + '\x1B[39m\n';
          }
        } else {
          if (index === this.choices.length - 1) { // 最后一行 不要加\n
            content += '  ' + choice.name + '\n';
          } else { // 不是最后一行,添加\n
            content += '  ' + choice.name + '\n';
          }
        }
      })
      // 空行 询问标题占两行
      this.height = this.choices.length + 2;
      return content;
    } else {
      const name = this.choices[this.selected].name;
      return '\x1B[32m?\x1B[39m \x1B[1m' + this.message + '\x1B[22m\x1B[0m \x1B[36m' + name + '\x1B[39m\x1B[0m \n';
    }
  }


  clean() {
    const emptyLines = ansiEscapes.eraseLines(this.height);
    this.output.write(emptyLines);
  }
  close() {
    this.output.unmute();
    this.rl.output.end();
    this.rl.pause();
    this.rl.close();
  }
}

function prompt(option) {
  return new Promise((resolve, reject) => {
    try {
      const list = new List(option);
      list.render();
      list.on('exit', s => resolve(s));
    } catch(e) {
      reject(e);
    }
  })
} 

prompt(option).then((result) => {
    console.log(result);
  }
);
Copyright © imooc-lego (2020 - present) all right reserved,powered by GitbookFile Modify: 2021-06-27 08:04:57

results matching ""

    No results matching ""