test-cli

141 阅读3分钟

今天突然发现公司大佬自实现的一个cli工具 可以实现构建项目及页面及组件,接下来学习一下吧!!!

了解目录结构

template

可以使用现成脚手架生成结构框架,可以自行实现

utils

配置文件,通用方法实现

package.json

{
  "name": "test-cli",
  "version": "1.0.0",
  "description": "try to achieve cli",
  "main": "index.js",
  "bin": {
    "t-cli": "bin/index.js"
  },
  "scripts": {
    "dev": "echo "hello dev"",
    "prod": "echo "hello prod""
  },
  "keywords": [
    "t-cli"
  ],
  "author": "Cindy",
  "license": "ISC",
  "dependencies": {
    "colors": "^1.4.0",
    "commander": "^6.2.1",
    "fs-extra": "^9.0.1",
    "inquirer": "^8.0.0",
    "loading-cli": "^1.1.0",
    "readline-sync": "^1.4.10"
  }
}

安装

npm init (-y) 生成package.json文件

name 设置了应用程序/软件包的名称。 【名称必须少于 214 个字符,且不能包含空格,只能包含小写字母、连字符(-)或下划线(_)。】

description 是应用程序/软件包的简短描述。

main 设置了应用程序的入口点。

author 列出软件包的作者 ---可以是字符串:"author": "duxin";也可以是对象:"author":{"name":"duxin"}

contributors 可以有一个或多个贡献者,为数组格式

license 软件包的许可证

bugs 链接到润简报的问题跟踪器,最常用:"bugs":"github.com/nodejscn/no…"

homepage 设置软件包的主页

version 表明了当前的版本。

private 如果设置为 true,则可以防止应用程序/软件包被意外地发布到 npm。

scripts 定义了一组可以运行的 node 脚本。

dependencies 设置了作为依赖安装的 npm 软件包的列表。

devDependencies 设置了作为开发依赖安装的 npm 软件包的列表。

engines 设置了此软件包/应用程序在哪个版本的 Node.js 上运行。

browserslist 用于告知要支持哪些浏览器(及其版本)。

sideEffects

bin 是命令名到本地文件名的映射

{
  "bin": {
      "test-cli": "bin/index.js"
  }
}

bin文件夹(index.js)

commander

安装: npm install commander
声明program变量:const { program } = require('commander')
几个命令
command :自定义执行的命令
oprton:自定义选项
description:命令的描述
action:命令执行之后执行的方法
parse:解析命令行参数,放在最后
alias 定义命令的别名 描述 方法
const commander = require("commander")

commander.command("version") //第一个参数为命令名称
                .alias("v")// 简写
                .description("version ") // 描述
                // .options('-i, --init', '初始化项目') // ('-短链 --长链', description)
                .action(function () { // 命令执行后的方法 })

Inquirer

特点:提供错误反馈;询问问题;解析输入;验证答案;管理分层提示
安装:npm install inquirer
使用:
 var inquirer = require("inquirer"); inquire.prompt(question) -> promise
const commander = require("commander")
const inquirer = require("inquirer")
/**
 * 初始化项目
 * promptInit: 为问题数组
 */
commander
    .command("init")
    .alias("i")
    .description("init")
    .action(function () {
        inquirer.prompt(promptInit).then(answers => {
            console.log(answers)
            // handlers.createNewProject(answers)
        })
    });

输出:

调用 inquirer.prompt([参数]).then(answers => { 逻辑 })

参数 type(string):会话类型,默认是input

支持类型包含 input(用户输入型);confirm(确认会话型);list(无序列表型); rawlist(有序列表型);expand(扩展列表);checkbox(勾选型);password(输入密码型);editor(编辑型)

    name(String): 当存储答案时,name作为答案的key值--映射
    message(String|Function):问题的题目描述
    default(String|Number|Array|Function):答案的默认值
    choices(Array | Function)
    validate(Function):校验用户输入参数的方法,回调函数内传递两个参数,第一个是用户输入的参数,第二个是之前所有绘画的答案,正确为true
    filter(Function):对用户输入的答案,经过处理后返回
    when(Function,Boolean):当满足函数内的条件时,当前问题才能出现,返回自为Boolean,函数参数是之前所有的答案
    pageSize(Number):可是区域内选项的个数,适用于type为list,rawList,expend or checkbox
    prefix:添加message前缀信息
    suffix:添加message后缀信息

分隔符 new inquirer.Separator() 分隔符可以加在choices的数组中 (借鉴)

完整代码

#!/usr/bin/env node
const commander = require("commander")
const path = require("path")
const inquirer = require("inquirer")
const promptInit = [
    {
        type: "input",
        message: "输入项目名称:",
        name: "name",
        default: "MyProject",
    },
    {
        type: "list",
        message: "选择项目类型:",
        name: "type",
        choices: [
            "Vue-MPA",
            "React-MPA",
            "Vue-MPA",
            "React-SPA",
            "TS-UMD",
            "Vue-Plugin",
        ],
    },
]

/**
 * 获取版本号
 */
commander
    .command("version")
    .alias("v")
    .description("version")
    .action(function () {
        let package = require(path.resolve(__dirname, "../package.json"));
        console.log(package.version)
    });
/**
 * 初始化项目
 * promptInit: 为问题数组
 */
commander
    .command("init")
    .alias("i")
    .description("init")
    // .options('-i, --init', '初始化项目')
    .action(function () {
        inquirer.prompt(promptInit).then(answers => {
            console.log(answers)
        })
    });