xzh-cli

1.0.1 • Public • Published

@TOC

创建工程

mkdir vue-auto-router-cli
cd vue-auto-router-cli
npm init -y
npm i commander download-git-repo ora handlebars figlet clear chalk open -s

建立文件目录

bin/xzh.js

#! /usr/bin/env node
console.log('start!!!!!')

package.json

"bin":{
    "xzh":"./bin/xzh.js"
}//意思是当输入‘xzh’这个命令时执行"./bin/xzh.js"这个文件

安装这个包

npm link   

相当于暂时的全局安装vue-auto-router-cli

运行

xzh

image-20200819014217202

如图输出了我写的log

编写第一个功能

编写xzh.js

#! /usr/bin/env node
const program = require('commander') //用于程序显示的包
program.version(require('../package.json').version)  //xzh -V 输出版本号 //从package.json中获取版本
program.command('init <name>') //定义一个命令
    .description('init project')  //编写对这个命令的描述
    .action(name =>{   //定义命令要实现的功能
        console.log('init '+ name)
    })
program.parse(process.argv)   //解析命令行输入的参数

执行

xzh init vue

image-20200819015243813

成功执行了init命令,输入了“init vue”

xzh -V

image-20200819015432797

成功输出版本号

重新实现第一个功能

建立文件目录

/lib/init.js

const {promisify} = require('util')  //用于让异步方法Promise化
const figlet =promisify(require('figlet'))   //用于将小的文字通过拼接的方式放大
const clear = require('clear')  //用于清屏
const chalk = require('chalk')  //粉笔工具,用于美化log文字,比如让它有颜色
const log = content => console.log(chalk.green(content))  //用chalk重新定义log方法,让log文字变为绿色

module.exports = async name =>{
    //打印欢迎界面
    clear() //首先清屏
    const data = await figlet('XZH Welcome')
    log(data) //通过新的log打印出被放大后的文字
}

/bin/xzh.js中调用init方法

#! /usr/bin/env node
const program = require('commander') //用于程序显示的包
program.version(require('../package.json').version)  //xzh -V 输出版本号 //从package.json中获取版本
program.command('init <name>') //定义一个命令
    .description('init project')  //编写对这个命令的描述
    .action(require('../lib/init')) //!!!!!!!!!!!!!!!!!!!!!!!!!!!! 在这里引入init方法
program.parse(process.argv)   //解析命令行输入的参数

执行

xzh init vue

image-20200819021315804

成功输入放大后的文字

实现在GitHub上下载代码

GitHub地址

https://github.com/su37josephxia/vue-template

建立文件目录

/lib/download.js

const {promisify} = require('util')

/*
* repo github仓库的地址
* desc 将下载下来的文件放哪*/
module.exports.clone = async function(repo,desc){
    const download = promisify(require('download-git-repo'))  //用于下载git仓库
    const ora = require('ora')  // 用于界面显示正在下载
    const process = ora(`下载...... ${repo}`)
    process.start()  //启动显示,开始转圈圈
    await download(repo,desc)
    process.succeed() //下载成功,显示✔
}

init.js中调用download方法

const {promisify} = require('util')  //用于让异步方法Promise化
const figlet =promisify(require('figlet'))   //用于将小的文字通过拼接的方式放大
const clear = require('clear')  //用于清屏
const chalk = require('chalk')  //粉笔工具,用于美化log文字,比如让它有颜色
const log = content => console.log(chalk.green(content))  //用chalk重新定义log方法,让log文字变为绿色
const {clone} = require('../lib/download') //!!!!!!!!!!!!!!!!!!!!引入方法,调用可以下载git上的代码
module.exports = async name =>{
    //打印欢迎界面
    clear() //首先清屏
    const data = await figlet('XZH Welcome')
    log(data) //通过新的log打印出被放大后的文字

    log(`🚀创建项目:${name}`)
    await clone('github:su37josephxia/vue-template',name)  //开始下载git上的代码
}

执行

xzh init vue

image-20200819023753494

如果下载中‘|’蓝线会一直转动直到下载完成

image-20200819023918082

实现安装依赖

init.js

const {promisify} = require('util')  //用于让异步方法Promise化
const figlet =promisify(require('figlet'))   //用于将小的文字通过拼接的方式放大
const clear = require('clear')  //用于清屏
const chalk = require('chalk')  //粉笔工具,用于美化log文字,比如让它有颜色
const log = content => console.log(chalk.green(content))  //用chalk重新定义log方法,让log文字变为绿色
const {clone} = require('../lib/download') //!!!!!!!!!!!!!!!!!!!!引入方法,调用可以下载git上的代码

//重新定义一个子进程方法使得可以输出日志log
const spawn = async (...args)=>{
    const {spawn} = require('child_process') //子进程方法
    return new Promise(resolve =>{
        const proc = spawn(...args)   //返回一个子进程对象
        proc.stdout.pipe(process.stdout) // 通过管道的方式将子进程的输出流连接到主进程的输出流
        proc.stderr.pipe(process.stderr)// 通过管道的方式将子进程的错误流连接到主进程的错误流
        proc.on('close',()=>{  // 绑定进程事件'close',即当子进程关闭时,改变promise的状态为resolve
            resolve()
        })
    })

}
module.exports = async name =>{
    //打印欢迎界面
    clear() //首先清屏
    const data = await figlet('XZH Welcome')
    log(data) //通过新的log打印出被放大后的文字

    // 下载代码
    log(`🚀创建项目:${name}`)
    await clone('github:su37josephxia/vue-template',name)  //开始下载git上的代码

    // 安装依赖
    log('安装依赖...')
    await spawn('npm',['install'],{cwd: `./${name}`})  //前两个参数是npm install命令的拆分,第三个参数指定这条安装命令执行的路径
    log(chalk.green(`
    🆗安装完成:
    To get Start:
    ========================================
        cd ${name}
        npm run serve
    ========================================
    `))
}

执行

xzh init vue

ubuntu虚拟机执行正常,成功下载依赖。

windows 执行错误,原因未知,错误如下 :

image-20200819073250434

解决方案:

if (process.env.ComSpec){  //兼容windows系统
        await spawn('npm',['install'],{
            cwd: `./${name}`,
            shell: process.env.ComSpec
        })
    }else{
        await spawn('npm',['install'],{cwd: `./${name}`})  //前两个参数是npm install命令的拆分,第三个参数指定这条安装命令执行的路径
    }

参考nodejs文档:spawn的参数说明

自动开启本地服务,并打开浏览器

init.js

const {promisify} = require('util')  //用于让异步方法Promise化
const figlet =promisify(require('figlet'))   //用于将小的文字通过拼接的方式放大
const clear = require('clear')  //用于清屏
const chalk = require('chalk')  //粉笔工具,用于美化log文字,比如让它有颜色
const log = content => console.log(chalk.green(content))  //用chalk重新定义log方法,让log文字变为绿色
const {clone} = require('../lib/download') //!!!!!!!!!!!!!!!!!!!!引入方法,调用可以下载git上的代码
const open = require('open')  //用于打开浏览器

//重新定义一个子进程方法使得可以输出日志log
const spawn = async (...args)=>{
    const {spawn} = require('child_process') //子进程方法
    return new Promise(resolve =>{
        const proc = spawn(...args)   //返回一个子进程对象
        proc.stdout.pipe(process.stdout) // 通过管道的方式将子进程的输出流连接到主进程的输出流
        proc.stderr.pipe(process.stderr)// 通过管道的方式将子进程的错误流连接到主进程的错误流
        proc.on('close',()=>{  // 绑定进程事件'close',即当子进程关闭时,改变promise的状态为resolve
            resolve()
        })
    })

}
module.exports = async name =>{
    //打印欢迎界面
    clear() //首先清屏
    const data = await figlet('XZH Welcome')
    log(data) //通过新的log打印出被放大后的文字



    // 下载代码
    log(`🚀创建项目:${name}`)
    await clone('github:su37josephxia/vue-template',name)  //开始下载git上的代码

    // 安装依赖
    log('安装依赖...')
    if (process.env.ComSpec){  //兼容windows系统
        await spawn('npm',['install'],{
            cwd: `./${name}`,
            shell: process.env.ComSpec
        })
    }else{
        await spawn('npm',['install'],{cwd: `./${name}`})  //前两个参数是npm install命令的拆分,第三个参数指定这条安装命令执行的路径
    }

    log(chalk.green(`
    🆗安装完成:
    To get Start:
    ========================================
        cd ${name}
        npm run serve
    ========================================
    `))

    open('http:localhost:8080')
    if (process.env.ComSpec){  //兼容windows系统
        await spawn('npm',['run','serve'],{
            cwd: `./${name}`,
            shell: process.env.ComSpec
        })
    }else{
        await spawn('npm',['run','serve'],{cwd: `./${name}`})  //前两个参数是npm install命令的拆分,第三个参数指定这条安装命令执行的路径
    }
}

实现动态路由

建立文件目录

/lib/refresh.js

const fs = require('fs')  // 读取文件用的
const handlebars = require('handlebars') //字符串模板库引擎
const chalk = require('chalk') //粉笔工具

module.exports = async ()=>{
   const list = fs.readdirSync('./src/views')
       .filter(name => name !== 'Home.vue')
       .map(name =>{
           console.log('name:',name)
           return {
               name: name.replace('.vue','').toLowerCase(),
               file: name
           }
       })

   // 路由
   compile({list},'./src/router.js','./template/router.js.hbs')
   // 菜单
   compile({list},'./src/App.vue','./template/App.vue.hbs')
   /*
   * meta 数据定义
   * filePath 目标文件
   *  templatePath 模板文件
   *  */
   function compile(meta,filePath,templatePath) {
       if (fs.existsSync(templatePath)){
           const content = fs.readFileSync(templatePath).toString() //读取模板文件,并转换为字符串
           const result = handlebars.compile(content)(meta) //编译
           fs.writeFileSync(filePath,result)
           console.log(`🚀 ${filePath}创建成功`)


       }
   }
}

定义命令

#! /usr/bin/env node
const program = require('commander') //用于程序显示的包
program.version(require('../package.json').version)  //xzh -V 输出版本号 //从package.json中获取版本

program.command('init <name>') //定义一个命令
    .description('init project')  //编写对这个命令的描述
    .action(require('../lib/init'))

program.command('refresh')
    .description('refresh routers... ')
    .action(require('../lib/refresh'))

program.parse(process.argv)   //解析命令行输入的参数

执行

进入到vue目录下

vue的文件结构如下

├── src │ ├── App.vue │ ├── main.js │ ├── router.js │ └── views │ ├── About.vue │ ├── Home.vue │ └── more.vue └── template ├── App.vue.hbs └── router.js.hbs

执行

xzh refresh

image-20200819090603313

热更新

待完成

npm发布

待完成

Readme

Keywords

none

Package Sidebar

Install

npm i xzh-cli

Weekly Downloads

1

Version

1.0.1

License

ISC

Unpacked Size

31.6 kB

Total Files

10

Last publish

Collaborators

  • xiezh01