前端架构: 实现脚手架处理简单的命令注册和参数解析

实现简单的命令注册和参数解析


1 )概述

  • 这里不会使用任何第三方工具,而是给大家讲解一下参数解析的一个实现原理
  • 实现两个目标
    • 第一目标是注册一个命令 $ xyzcli init 这个命令就可以完成一个自己的操作
    • 第二个是实现参数解析
      • 希望能够实现 --version 的一个参数解析
      • 以及 init -name 这样的一个参数解析

2 )实现

  • 那么问题来了,如何能识别到这个 init 命令 $ xyzcli init

  • 在nodejs中有一个 process 的内置库

  • 在 process 中会有一个 argv 参数,这个就会把我们所有的参数给罗列下来

    • 第1个返回值是:当前node命令的具体路径
    • 第2个返回值是:当前脚手架命令,如xyzcli的具体路径
    • 第3个返回值是:command, 在这里可以就是 init
      #!/usr/bin/env node
      
      // 定义执行命令的库
      const lib = {
        init() {
          console.log('init')
        }
      }
      
      // 获取并解析 argv
      const { argv } = require('process');
      // console.log(argv)
      const command = argv[2];
      // console.log(command); // init
      if (command && lib[command]) {
        lib[command](); // 执行
      } else {
        console.log('请输入命令')
      }
      
  • 通过以上方法,就可以解析出来 init 命令

  • 那如果需要解析出 --name ooo 这种参数呢?

    #!/usr/bin/env node
    
    const { argv } = require('process');
    
    const options = argv.slice(3); // 解析从第3个后面
    let [option, param] = options;
    option = option.replace('--', '');
    
    // 测试参数
    console.log('option: ', option); // name
    console.log('param: ', param); // ooo
    
  • 如何应用参数呢?

    #!/usr/bin/env node
    
    // 定义执行命令的库
    const lib = {
      init({ option, param }) {
        console.log('执行 init 流程', option, param)
      }
    }
    
    // 获取并解析 argv
    const { argv } = require('process');
    const command = argv[2];
    let option, param;
    const options = argv.slice(3);
    if (options) {
      [option, param] = options;
      option = option.replace('--', '');
    }
    if (command && lib[command]) {
      lib[command]({ option, param }); // 执行
    } else {
      console.log('请输入命令')
    }
    
  • 注意,实际参数解析往往比较复杂,比如:

    • $ xyzcli init --name -p 22 --test 33
    • 这种往往参数比较复杂,而且对应的值非常不确定,这个时候,参数处理就会变得非常困难
    • 如果自己开发和兼容此类问题,将会占用非常大的工作
    • 通常我们用一些库进行处理, 这里只做原理解析
  • 对全局命令的处理 $ xyzcli --version

    • 注意,这里 --version 属于 command, 也就是出现在了 argv 的第三位
    • 这种,就是顶级的或全局的 option
      #!/usr/bin/env node
      
      // 定义执行命令的库
      const lib = {
        init({ option, param }) {
          console.log('init');
          console.log('执行 init 流程', option, param);
        },
        version: '1.0.0'
      }
      // 获取并解析 argv
      const { argv } = require('process');
      const command = argv[2];
      let option, param;
      const options = argv.slice(3);
      if (options.length) {
        [option, param] = options;
        option = option.replace('--', '');
      }
      
      // 执行命令
      if (command && lib[command]) {
        lib[command]({ option, param }); // 执行
      } else if(command.startsWith('--') || command.startsWith('-')) {
        // 这里是全局 options
        const globalOption = command.replace(/--|-/g, '');
        if (globalOption === 'version' || globalOption === 'V') {
          console.log(lib['version']);
        }
      } else {
        console.log('请输入命令')
      }
      
  • 以上演示,完成整个脚手架的一个初步版本开发

  • 注意这里不是成熟的案例,只是阐述如何做的原理

你可能感兴趣的:(Web,前端,架构)