UNPKG

penn-cli

Version:

快速生成cli项目的脚手架

264 lines (246 loc) 12.3 kB
#! /usr/bin/env node /*eslint-disable*/ // https://gitee.com/jipengju/dashboard/projects const program = require(`commander`) // 命令行中参数的处理 const inquirer = require(`inquirer`) // 命令行中的select 选择器 const downloadRepo = require(`download-git-repo`) // 仓库下载 const ora = require(`ora`) // Loading const figlet = require(`figlet`) // 生成好看的标识颜色 const Printer = require('@darkobits/lolcatjs') // 生成随机颜色 const chalk = require(`chalk`)//给提示文案着色 *注:5版本是esm,如果在ts中或者构建工具中使用,目前建议使用4版本 const myUtil = require(`./utils/myUtil`) // 私有工具集 const clear = require('clear') // 清屏 // 常量 const packageJson = require(`./package.json`) const cliName = packageJson.projectName // cli名称 const repoCurrentVersion = packageJson.version // 当前的版本 const repolatestVersionObj = myUtil.checkUpdateVersion(packageJson.name, repoCurrentVersion, packageJson.repository.npmUrl) // 获取最新的版本 const repoLastVersion = repolatestVersionObj.lastVersion // 上一次版本 const repolatestVersion = repolatestVersionObj.latest // 最新的版本 const repoNodeVersion = packageJson.engines.node // 获取工程依赖node版本 const nodeVersion = process.version // 系统node版本 const Log = console.log // 日志 // Log(repolatestVersionObj) // 全局变量 let Loading = null // 创建加载器 // 系统色彩变量 const repoColor = { warning: `#f40` // 警告 } // cli 图标 const repoLogo = figlet.textSync(`${cliName}`, { font: `epic`, horizontalLayout: `Smush (U)`, verticalLayout: `Smush (U)` }) // 检测node版本 if (!myUtil.checkNodeVersion(nodeVersion, repoNodeVersion)) return // CLI对象 const myCli = { /* * 执行回调 * projectName 项目名 * option 对应上面的指令选项 * */ // 检测是否存在重名项目 checkIsHasProject(projectName) { return new Promise((resolve, reject) => { if (myUtil.hasFileName(projectName)) { inquirer.prompt([ { type: 'list', name: 'DeleteAndUpdate', message: `检测到本地已存在名字为${projectName}的工程目录/文件,是否需要自动删除并创建?`, choices: [ { name: `自动删除并创建${chalk.hex(repoColor.warning)(`[该项会自动删除重名目录,请谨慎操作]`)}`, value: 1 }, { name: '手动删除', value: 0 } ] } ]).then((answer) => { if (!answer.DeleteAndUpdate) { resolve(answer.DeleteAndUpdate) return } myUtil.deleteDir(ora, projectName).then(t => { resolve(answer.DeleteAndUpdate) }) }) } else { resolve(true) } }) }, // 拉取项目 cloneProject(url, name) { Loading = ora({ text: chalk.greenBright(`正在拉取脚手架...`) }).start() // 开始状态 => 加载状态 downloadRepo( `direct:${url}`, name, { clone: true }, err => { if (err) return Loading.warn(chalk.redBright(`=====| 脚手架已存在或仓库资源错误 |=====`)) // 加载状态 => 成功状态 Loading.succeed(chalk.greenBright(`=========| 脚手架创建成功 |=========`)) // 加载状态 => 成功状态 Loading.succeed(chalk.greenBright(`------------------------------------`)) // 加载状态 => 成功状态 Loading.succeed(chalk.greenBright(`------------------------------------`)) // 加载状态 => 成功状态 Loading.succeed(chalk.greenBright(`------------------------------------`)) // 加载状态 => 成功状态 Loading.succeed(chalk.greenBright(`============| 运行指南 |============`)) // 加载状态 => 成功状态 Loading.succeed(chalk.greenBright(`====| ${Printer.fromString(`npm install`)} [拉取依赖] |====`)) // 加载状态 => 成功状态 Loading.succeed(chalk.greenBright(`====| ${Printer.fromString(`npm run serve`)} [项目启动] |====`)) // 加载状态 => 成功状态 } ) }, // cli 初始化 _init(projectName, option) { clear() // welcome Log(chalk.blueBright(repoLogo)) Log(chalk.blueBright(`Hello, Welcome to ${cliName}!`)) // cli init const projectType = Object.keys(option).length ? Object.keys(option)[0].toLowerCase() : null // 类型判断 if (projectType) { // 默认指令 Log(chalk.green(`去生成一个web-${projectType}...`)) myCli.checkIsHasProject(projectName).then(isHas => { if (!isHas) { Log(chalk.hex(repoColor.warning)(`请自行删除本地的${projectName}工程目录/文件!`)) return } myCli.cloneProject(packageJson.repository[`${projectType}Url`], projectName) }) } else { // 自定义 Log(chalk.hex(repoColor.warning)(`你好,欢迎使用${cliName}!`)) //筛选问题 const questions = [ { type: 'input', name: 'customProjectName', message: '请输入项目名称:', validate: function (val) { if (val.match(/^[A-Za-z0-9\( \)\-\#]+$/g)) { return true } return '请输入规范的项目名称' }, when: (answer) => { if (!answer.customProjectName) { return true } return false } }, { type: `list`, name: `framework`, message: `请选择需要的脚手架:`, default: `pc-|cut|-${packageJson.repository.pcUrl}`, choices: [ { name: 'pc端脚手架', value: `pc-|cut|-${packageJson.repository.pcUrl}` }, { name: '移动端脚手架', value: `h5-|cut|-${packageJson.repository.h5Url}` } ], when: (answer) => { if (answer.customProjectName) { Log(chalk.red(`\n\nVue CLI v4.5.13`)) if (repolatestVersion > repoCurrentVersion) { Log(` ┌───────────────────────────────────────────┐ │ │ │ Hello, I'm Penn Ji. │ │ the author of Penn-CLI. │ │ ${Printer.fromString(`Welcome to `)}${Printer.fromString(`use it.`)} │ │ │ │ Your current version is ${chalk.red(`${repoCurrentVersion}`)} │ │ New version available ${chalk.hex(repoColor.warning)(`${repoLastVersion}`)}${chalk.hex(repoColor.warning)(`${repolatestVersion}`)} │ │ Run ${chalk.hex(repoColor.warning)(`npm i -g penn-cli`)} to update! │ │ │ └───────────────────────────────────────────┘ `) } else { Log(` ┌───────────────────────────────────────────┐ │ │ │ Hello, I'm Penn Ji. │ │ the author of Penn-CLI. │ │ ${Printer.fromString(`Welcome to `)}${Printer.fromString(`use it.`)} │ │ │ │ Your current version is ${chalk.red(`${repoCurrentVersion}`)} │ │ You're the ${chalk.greenBright(`latest version`)}! │ │ │ └───────────────────────────────────────────┘ `) } } return true } } ] // 自定义默认项 const answers = { customProjectName: projectName } // Log(`answers==>${JSON.stringify(answers)}`) inquirer.prompt(questions, answers) .then((answer) => { if (answer.framework) { const frameworkArr = answer.framework.split(`-|cut|-`) answer.frameworkObj = { name: frameworkArr[0], url: frameworkArr[1] } Log(JSON.stringify(answer)) Log(chalk.green(`去生成一个web-${answer.frameworkObj.name}...`)) const _projectName = answer.customProjectName myCli.checkIsHasProject(_projectName).then(isHas => { if (!isHas) { Log(chalk.hex(repoColor.warning)(`请自行删除本地的${_projectName}工程目录/文件!`)) return } myCli.cloneProject(packageJson.repository[`${answer.frameworkObj.name}Url`], _projectName) }) } else { return } }) } }, // 构建 _build() { // 开始构建 program .version( // 彩虹色logo Printer.fromString( ` \n Penn-CLI v${repoCurrentVersion}\n ${repoLogo}\n Hello, Welcome to ${cliName}!` ) ) // 获取版本 以package.json 版本信息为准 .description(`欢迎使用${cliName}脚手架~`) // 脚手架描述 .option(`-F, --framework`, `指定创建的脚手架,目前支持web-pc和web-h5`) // 指定构建的脚手架 .configureOutput({ // 此处使输出变得容易区分 writeOut: (str) => process.stdout.write(`[OUT] ${str}`), writeErr: (str) => process.stdout.write(`[ERR] ${str}`), // 将错误高亮显示 // outputError: (str, write) => write(chalk.hex(repoColor.warning)(str)) outputError: (str, write) => write(chalk.red(str)) }) .command(`create [projectName]`) .description(`创建脚手架`) .option(`-pc`, `生成一个用于web-pc的项目脚手架`) .option(`-h5`, `生成一个用于web-h5的项目脚手架`) .action((projectName, option, command) => (myCli._init(projectName, option))) program.parse(process.argv) // 解析指令 } } myCli._build()