美文网首页
初探交互式命令行

初探交互式命令行

作者: 说叁两事 | 来源:发表于2021-01-24 23:49 被阅读0次

    Node原生实现命令行

    function cli () {
      process.on('exit', function () {
        console.log('----exit')
      })
      process.stdin.setEncoding('utf8')
      process.stdout.write('......\n')
      console.log('----------------00000000000------------')
      process.stdout.write('确认执行吗(y/n)?')
      process.stdout.write('......\n')
      process.stdin.on('data', (input) => {
        input = input.toString().trim()
        if (['Y', 'y', 'YES', 'yes'].indexOf(input) > -1) {
          console.log('success')
        }
        if (['N', 'n', 'No', 'no'].indexOf(input) > -1) {
          console.log('reject')
        }
        console.log('===========callback============')
        process.exit(0)
      })
    }
    cli()
    

    巨人肩膀上的命令行实现

    在前人的基础上,自定义交互脚本是一个很简单的事情。

    这里介绍四个工具,分别作用在不同的领域:

    • shelljs
      • 执行脚本程序
    • inquirer
      • 命令行用户交互界面
    • chalk
      • 命令行日志样式
      • 可嵌套、可链式
    • commander
      • 自定义命令行参数
    // const spawn = require('child_process').spawn
    // const { Command } = require('commander')
    const shell = require('shelljs');
    const inquirer = require('inquirer');
    const chalk = require('chalk');
    const scriptsConfig = require('../config/scripts')
    const runModes = require('../config/modes')
    
    // const program = new Command();
    let curScriptEvent = process.env.npm_lifecycle_event;  // E.g.:'npm run serve'中的'serve'
    let curScriptSource = process.env.npm_lifecycle_script;  // E.g.:'npm run serve: vue-cli-service serve'的'vue-cli-service serve'
    
    
    const build = async () => {
      let res;
      try {
        // j、k或者数字键选择
        res = await inquirer.prompt([
          {
            type: 'list',
            name: 'operation',
            message: '请选择你要运行的命令:npm run',
            choices: ['serve', 'build', 'push', 'fds', 'test']
          },
          {
            type: 'list',
            name: 'mode',
            message: '请选择你要执行的环境?',
            choices: ['dev', 'prev', 'pro']
          },
        ]);
      } catch(e) {
        if (e.isTryError) {
          console.log(chalk.red("Prompt couldn't be rendered in the current environment"))
        } else {
          console.log(chalk.red("Error:", e))
        }
      }
      const { operation, mode } = res;
      console.log(chalk.green(`正在执行操作npm run ${operation}---${mode}......`));
      curScriptEvent = `${operation}${mode ? (':' + mode) : ''}`
      curScriptSource = scriptsConfig[curScriptEvent]
    
      if (process.platform === 'win32') {
        shell.exec(`npx cross-env ${curScriptSource}`)
        // spawn('npx cross-env', [curScriptSource], {
        //   stdio: 'inherit',
        //   shell: true
        // })
      } else {
        shell.exec(`npm run ${curScriptEvent}`)
        // spawn('npm', ['run', curScriptEvent])
      }
    }
    build();
    
    
    

    优化版:

    const shell = require('shelljs');
    // const spawn = require('child_process').spawn;
    const inquirer = require('inquirer');
    const chalk = require('chalk');
    const { scripts, getRunModes } = require('../config/scripts')
    const runModes = getRunModes(scripts)
    const operationKeys = Object.keys(runModes)
    
    let curScriptEvent = process.env.npm_lifecycle_event;  // E.g.:'npm run serve'中的'serve'
    let curScriptSource = process.env.npm_lifecycle_script; // E.g.:'npm run serve: vue-cli-service serve'的'vue-cli-service serve'
    
    const build = async () => {
      let operation, mode;
      try {
        // j、k或者数字键选择
        const res = await inquirer.prompt({
          type: 'list',
          name: 'operation',
          message: '请选择你要运行的命令:npm run',
          choices: operationKeys
        });
        operation = res.operation
      } catch(e) {
        if (e.isTryError) {
          console.log(chalk.red("Prompt couldn't be rendered in the current environment"))
        } else {
          console.log(chalk.red("Error:", e))
        }
      }
      try {
        // j、k或者数字键选择
        const res = await inquirer.prompt({
          type: 'list',
          name: 'mode',
          message: '请选择你要执行的环境?',
          choices: runModes[operation]
        });
        mode = res.mode
      } catch(e) {
        if (e.isTryError) {
          console.log(chalk.red("Prompt couldn't be rendered in the current environment"))
        } else {
          console.log(chalk.red("Error:", e))
        }
      }
      // const { operation, mode } = res;
      // const NODE_ENV = runModes[mode];
      curScriptEvent = `${operation}${mode ? (':' + mode) : ''}`
      curScriptSource = scripts[curScriptEvent]
      console.log(chalk.green(`正在执行${curScriptSource}......`));
    
      if (process.platform === 'win32') {
        // spawn('npx cross-env', [curScriptSource], {
        //   stdio: 'inherit',
        //   shell: true
        // })
        shell.exec(`npx cross-env ${curScriptSource}`)
      } else {
        shell.exec(curScriptSource)
        // spawn('npm', ['run', curScriptEvent], {
        //   stdio: 'inherit',
        //   shell: true
        // })
      }
    }
    build();
    

    相关文章

      网友评论

          本文标题:初探交互式命令行

          本文链接:https://www.haomeiwen.com/subject/nvovzktx.html