最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 如何开发一个cli工具

    正文概述 掘金(云积分大前端团队)   2021-06-30   656

    脚手架可以帮助我们通过简单的命令来快速构建内容,目前比较常见的脚手架有vue-cli、create-react-app等,它是团队提升效率的重要手段。我们可以结合公司的业务来开发自己的脚手架工具。下面我将一步一步的开发一个脚手架工具,跟着我一起吧!

    1. 准备

    首先,需要确保你已经安装了node,然后我们来初始化一个项目

    mkdir mycli-demo & cd mycli-demo
    npm init -y
    

    如何开发一个cli工具

    2. 添加一个简单的命令

    在package.json中添加bin配置,mycli是我们cli工具提供的命令名称,对应的值是文件入口,我们这里指向bin/cli.js文件

    {
      "name": "mycli-demo",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
    + "bin":{
    +   "mycli": "./bin/cli.js"
    + },
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC"
    }
    

    在项目中创建bin/cli.js,并打印一段文字

    #!/usr/bin/env node
    
    console.log("i'm a cli")
    

    此时我们可以再控制台运行mycli

    如何开发一个cli工具

    你可能会上述错误,控制台找不到我们的cli工具,这是因为我们在使用一个工具的时候必须安装它,例如你没有安装npm的时候去使用也会遇到同样的错误。

    由于我们的mycli并没有发布,因此可以借助npm link或者yarn link选择本地安装,执行:

    npm link
    
    yarn link
    

    然后再执行mycli,就可以看到控制台输出了bin/cli.js中打印的内容

    如何开发一个cli工具

    至此,我们已经了解cli工具是如何作用的,下面我们在此基础上做一些改进,让他可以处理参数,彩色打印,显示加载中等等功能

    3. 处理参数

    很多时候我们需要在运行cli工具时携带参数,那么如何获取到这个参数呢?

    node程序中,通过process.argv可获取到命令的参数,以数组返回

    如何开发一个cli工具

    可以看到其实我们已经拿到各个参数,但是这样的获取方式不太直观,所以我们引入一个第三方npm包帮我们处理这部分功能:commander,参考文档:commander文档

    npm i commander -S
    

    我们在bin/cli.js添加如下代码

    #!/usr/bin/env node
    + const program = require('commander')
    
    console.log("i'm a cli")
    
    // 打印参数
    console.log(process.argv)
    
    + program
    +  .command('create <projectName>')
    +  .description('create a new project')
    +  .alias('c')
    +  .option('-r, --react', 'react template')
    +  .option('-v, --vue', 'vue template')
    +  .option('-v2, --vue2', 'vue2 template')
    +  .option('-v3, --vue3', 'vue3 template')
    +  .action((projectName, options) => {
    +    console.log(projectName, options)
    + })
    + program.version('1.0.0').parse(process.argv)
    

    到目前为止,我们可以直观的获取到命令的参数,你可以在控制台尝试一下

    4. 交互式命令

    有的时候我们可能需要在命令行工具中融入一些交互,根据用户的输入或者选择生成一些东西或者做相应的操作。我们可以引入一个npm包来帮我们实现:inquirer

    npm i inquirer -S
    

    我们在bin/cli.js添加如下代码

    #!/usr/bin/env node
    const program = require('commander')
    + const inquirer = require('inquirer')
    
    console.log("i'm a cli")
    
    // 打印参数
    console.log(process.argv)
    
    program
      .command('create <projectName>')
      .description('create a new project')
      .alias('c')
      .option('-r, --react', 'react template')
      .option('-v, --vue', 'vue template')
      .option('-v2, --vue2', 'vue2 template')
      .option('-v3, --vue3', 'vue3 template')
      .action((projectName, options) => {
        console.log(projectName, options)
    +   inquirer
    +     .prompt([
    +       {
    +         type: 'list',
    +         name: 'frameTemplate',
    +         message: '请选择框架类型',
    +         choices: ['Vue3', 'Vue2', 'React']
    +       }
    +     ])
    +     .then((answer) => {
    +       console.log(answer)
    +     })
      })
    program.version('1.0.0').parse(process.argv)
    
    

    我们在控制台运行

    mycli create test -r
    

    得到:

    如何开发一个cli工具 至此,我们完成了交互式命令,下面我将完成一个模板的下载,一起动手吧!

    5. 完成一个模板下载

    在前面的步骤中,我们发现我们的日志打印不是很友好,我们可以通过log-symblos chalk ora 帮我们做一些提示信息的优化

    npm包名称作用官网备注
    chalk修改控制台中字符串的样式chalk字体样式、颜色、背景颜色log-symbols各种日志级别的彩色符号log-symbols从5版本开始使用ESMRelease v5.0.0ora终端加载效果ora
    npm i chalk log-symbols@4 ora -S
    

    要下载一个github仓库的代码,我们需要引入download-git-repo, download-git-repo - npm

    npm i download-git-repo -S
    

    我们来实现一个简单的下载功能

    #!/usr/bin/env node
    const program = require('commander')
    const inquirer = require('inquirer')
    + const ora = require('ora')
    + const download = require('download-git-repo')
    + const { errLog, successLog } = require('../src/utils/log.js')
    
    console.log("i'm a cli")
    
    // 打印参数
    console.log(process.argv)
    
    program
      .command('create <projectName>')
      .description('create a new project')
      .alias('c')
      .option('-r, --react', 'react template')
      .option('-v, --vue', 'vue template')
      .option('-v2, --vue2', 'vue2 template')
      .option('-v3, --vue3', 'vue3 template')
      .action((projectName, options) => {
        console.log(projectName, options)
        inquirer
          .prompt([
            {
              type: 'list',
              name: 'frameTemplate',
              message: '请选择框架类型',
              choices: ['Vue3', 'Vue2', 'React']
            }
          ])
          .then((answer) => {
            console.log(answer)
    +       const spinner = ora()
    +       spinner.text = '正在下载模板...'
    +       spinner.start()
    +       download(
    +         '',
    +         projectName,
    +         { clone: true },
    +         function (err) {
    +           if (err) {
    +             spinner.fail('模板下载失败')
    +             errLog(err)
    +           } else {
    +             spinner.succeed('模板下载成功')
    +             successLog('项目初始化完成')
    +           }
    +         }
    +       )
          })
      })
    program.version('1.0.0').parse(process.argv)
    

    在控制台输入

     mycli create test -r
    

    可以看到模板下载成功

    至此,我们已经实现了一个简单的模板仓库下载功能。更多的功能大家可以自行尝试。

    如果我们想让其他小伙伴使用,我们需要把这个cli发布到npm,如何发布不在此篇文章展开叙述。

    6. 项目优化

    如果我们有多个命令,那么我们就需要写多个

    program
      .command('')
      .description('')
      .alias('')
      .option('')
      .action(() => {
        // 命令处理
      })
    
    1. 因为这部分代码被重复使用,我们自然而然想到了遍历,首先声明一个list变量用来维护我们的命令配置,在src新建command-config.js文件,该文件导出配置
    const COMMAND_LIST = [
      {
        command: 'create <projectName>',
        description: 'create a new project',
        alias: 'c',
        options: [
          ['-r, --react', 'react template'],
          ['-v, --vue', 'vue template'],
          ['-v2, --vue2', 'vue2 template'],
          ['-v3, --vue3', 'vue3 template']
        ],
        action: require('./commandHandler/create'),
        examples: ['-r', '--react', '-v', '--vue', '-v2', '--vue2', '-v3', '--vue3'].map((v) => `create projectName ${v}`)
      }
    ]
    
    module.exports = COMMAND_LIST
    
    

    修改bin/cli.js

    /**
     * 注册option
     * @param {Object} commander commander实例
     * @param {Object} option 每个命令配置对象
     * @returns commander
     */
    const registerOption = (commander, option) => {
      return option && option.length ? commander.option(...option) : commander
    }
    /**
     * 注册action
     * @param {Object} commander commander实例
     * @param {Object} commandEle 每个命令配置对象
     * @returns commander
     */
    const registerAction = (commander, commandEle) => {
      const { command, description, alias, options, action } = commandEle
      const c = commander
        .command(command) // 命令的名称
        .description(description) // 命令的描述
        .alias(alias)
      // 循环options
      options && options.reduce(registerOption, c)
      c.action(action)
      return commander
    }
    
    // 循环创建命令
    COMMAND_LIST.reduce(registerAction, program)
    
    1. 由于命令处理部分代码量较大,所以我们考虑把命令处理的函数提取在一个文件夹下,我们在src下新建commandHandler目录,并新建一个create.js,把create命令的处理代码放进create.js

    2. 为了更方便使用,我们改写mycli --help命令

    
    // help命令 把example显示出去
    const help = () => {
      console.log('\n')
      console.log(chalk.green('如何使用:'))
      COMMAND_LIST.forEach((command, index) => {
        console.log('  ', chalk.keyword('orange')(index + 1), `${command.command}命令`)
        command.examples.forEach((example) => {
          console.log(`     - mycli ${example}`)
        })
      })
    }
    
    program.on('-h', help)
    program.on('--help', help)
    

    此时我们输入mycli --help

    如何开发一个cli工具

    至此我们完成了一个简易版cli工具的开发

    源码:github.com/enbrands/st…

    main分支只git init该项目,其他分支每个分支完成一个步骤


    起源地下载网 » 如何开发一个cli工具

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元