搭建一个简单的cli工具

目前公司采用的项目结构是基于vue-cli脚手架,再在基础上进行通用组件、业务组件的封装和抽离,目前已经比较完善和稳定。但每次一个新的项目入厂,需要复制拷贝到新的项目目录,比较繁琐,通过搭建一个简单的cli工具,那么几个命令行就解决了。

其实大致的原理为:通过命令行来识别具体的信息,然后直接下载远程git仓库的代码到本地机器。

搭建具体流程

  1. 创建项目文件夹tcy-cli
  2. npm init初始化package.json
  3. 安装commander、download-git-repo依赖包
  4. 安装修改控制台输出内容样式的chalk、好看的加载圆圈效果ora非必选
  5. 编写相关脚手架命令行识别代码
  6. 发布到npm

安装包的时候,不要使用--save-dev,因为包的依赖信息会放在devDependencies中,这样在全局安装脚手架的时候,不会安装依赖包,要使用--save

commander可以对命令行做解析的库,可以解析我们在命令行输入,如tcy-cli init

inquirer是常规交互式命令行用户接口的集合,提供给 Node.js 一个方便嵌入,漂亮的命令行接口,功能有简化询问终端用户问题,解析,验证答案,提供错误反馈等等

download-git-repo可以下载git仓库的代码

具体代码

#! /usr/bin/env node

const program = require('commander');
const download = require('download-git-repo')
const inquirer = require('inquirer')
const chalk = require('chalk')
const ora = require('ora')
const fs = require('fs')

const spinner = ora(chalk.yellow('Downloading template ...'))

const Version = '1.1.7'

// 修改项目package.json
function setPackage(projectName, answers) {
    const packagePath = `${projectName}/package.json`
    const packageJson = fs.readFileSync(packagePath, 'utf-8')
    const packageResult = JSON.stringify(Object.assign(null, JSON.parse(packageJson), answers), null, 4)
    fs.writeFileSync(packagePath, packageResult)
}

// 修改项目名称配置文件
function setProjectName(projectName, fullName, shortName) {
    const configPath = `${projectName}/src/conf/index.js`;
    const str =
    `// 项目全称
const FullName = '${fullName}'

// 项目简称
const ShortName = '${shortName}'

export {
    FullName,
    ShortName
}
    `
    fs.writeFileSync(configPath, str)
}

// 设置空业务路由
function setEmptyRouterMap(projectName) {
    const routerPath = `${projectName}/src/router/asyncRouterMap.js`
    const str =
    `// 业务路由表
export const asyncRouterMap = []
`
    fs.writeFileSync(routerPath, str)
}

// 名称校验
function validateName(val) {
    if(/^[\u4e00-\u9fa5]+$/.test(val)) {
        return true
    } else {
        return "name must be chinaese"
    }
}

// 问答内容
const promptList = [
    // 项目全称
    {
        type: 'input',
        message: 'please set project fullname',
        name: 'fullName',
        validate: validateName
    },
    // 项目简称
    {
        type: 'input',
        message: 'please set project shortname',
        name: 'shortName',
        validate: validateName
    },
    // 是否需要初始演示路由
    {
        type: 'list',
        message: 'do you need a example router:',
        name: 'router',
        default: 'no',
        choices: [
            "no",
            "yes"
        ]
    }
]

program.version(Version, '-v, --version')
    .command('init ')
    .action((projectName) => {
        inquirer.prompt(
            promptList
        ).then(answers => {
            spinner.start()
            download('github:tianzhu1992/blocks-admin-vue', projectName, (err) => {
                spinner.succeed()
                const {fullName, shortName, router} = answers

                // 设置package.json的名称与版本号
                setPackage(projectName, {name: projectName, version: Version})

                // 修改项目名称信息
                setProjectName(projectName, fullName, shortName)

                // 设置静态初始路由
                if(router === 'no') {
                    setEmptyRouterMap(projectName)
                }

                // 下载代码成功/失败提示
                console.log(err ? chalk.red('Something Wrong In Download Template') : chalk.green('Download Template Success'))
            })
        });
    })
program.parse(process.argv);

  • #! /usr/bin/env node是执行这个文件时使用node方式执行
  • program.version是解析别人输入tcy-cli -vtcy-cli --version时输出的版本号
  • command指定和解析用户输入的信息,通过来匹配相应的输入信息
  • action是根据解析的输入信息来获取仓储并在回调执行接下来的任务
  • inquirer.prompt根据定义的问题来收集用户填写的内容,并在回调的形参answers中以键值对的形式展现
  • download的第一个参数下载地址不是填我们git的网址,按照上述的格式填就行,第二个参数是生成的项目名,第三个参数是错误的回调执行函数,如果没有错误信息,则表示执行成功

发布到npm

首先得需要一个npm账号,如没有,利用邮箱注册下https://www.npmjs.com/

登录账号

npm login

发布到npm

npm publish

你可能感兴趣的:(搭建一个简单的cli工具)