1. Build structure and dependencies
mkdir mycli
cd mycli
npm init -y
npm i commander download-git-repo ora handlebars figlet clear chalk open -s
Copy the code
  1. Setting the startup command

Create the startup script bin/run.js

#! /usr/bin/env node
//  #! The /usr/bin/env command is used to tell the user to find node in the path directory, #! The /usr/bin/env node allows the system to dynamically look up nodes// It can passwhichNode finds /usr/where node is installedlocal/bin/node
const program = require("commander") 
// const init = require(".. /lib/init"// define the version -v response program.version(require(".. /package.json").version) //< > and [] represent mandatory and optional fields respectively. Action returns the corresponding input parameter name program.command("init <name>").description("init project").action(require(".. /lib/init"Parse (process.argv)Copy the code

The package.json is modified as follows

"bin": {
"jc": "./bin/run.js"
},
Copy the code
  1. Customize the initialization interface

lib/init.js


const {promisify} = require("util")
const figlet = promisify(require('figlet'))
const chalk = require("chalk")
const clear = require("clear")
const clone = require(".. /lib/download")
// Add color output console
const colorLog = content= >  console.log(chalk.redBright(content))

module.exports = async name => {
    clear()/ / clear screen
    const data = await figlet("welcome to jason cli")// Convert text to output
    colorLog(data)/ / print
    //name is the name of the folder just created by init
    await clone('github:mjsong07/myComponent', name)
}

Copy the code
  1. Encapsulate the download code logic

lib/download.js


const {promisify} = require("util")
const ora = require("ora")
module.exports = async (repo,filderPath) => {
    const download = promisify(require("download-git-repo"))
    // Process prompt
    const process = ora(`downloading ${repo}`)
    process.start()
    await download(repo,filderPath)
    process.succeed();
}
Copy the code
  1. Added dependencies to install and automatically open web pages, run commands

Optimize init.js code

const { promisify } = require('util')
const figlet = promisify(require('figlet'))
const clear = require('clear')
const chalk = require('chalk')
const { clone } = require('./download')
const spawn = async(... args) => {const { spawn } = require('child_process')
    return new Promise(resolve= > {
        constproc = spawn(... args) proc.stdout.pipe(process.stdout) proc.stderr.pipe(process.stderr) proc.on('close'.() = > {
            resolve()
        })
    })
}
const log = content= > console.log(chalk.green(content))
module.exports = async name => {
    // Print the welcome screen
    clear()
    const data = await figlet('KKB Welcome')
    log(data)
    // Create the project
    log('🚀 create project:' + name)
    // Clone code
    await clone('github:mjsong07/myComponent', name)
    log('Install dependencies')
    await spawn('npm'['install'] and {cwd: `. /${name}` })
    log(` 👌 installation is complete: To get the Start: = = = = = = = = = = = = = = = = = = = = = = = = = = = CD${name}
    npm run serve
===========================
            `)

    const open = require('open')
    open('http://localhost:8080')
    await spawn('npm'['run'.'serve'] and {cwd: `. /${name}`})}Copy the code

Bin \serve.js starts the service

const spawn = (. args) = > {
    const { spawn } = require('child_process');
    constproc = spawn(... args) proc.stdout.pipe(process.stdout) proc.stderr.pipe(process.stderr)return proc
}

module.exports = async() = > {const watch = require('watch')
    let process
    let isRefresh = false
    watch.watchTree('./src'.async (f) => {
        if(! isRefresh) { isRefresh =true
            process && process.kill()
            await require('./refresh') ()setTimeout(() = > { isRefresh = false }, 5000)
            process = spawn('npm'['run'.'serve'])}})}Copy the code

Bin \refresh. Js Refreshes the routing code

const fs = require('fs')
const handlebars = require('handlebars')
const chalk = require('chalk')
module.exports = async() = > {// Get the page list
    const list =
        fs.readdirSync('./src/views')
            .filter(v= >v ! = ='Home.vue')
            .map(v= > ({
                name: v.replace('.vue'.' ').toLowerCase(),
                file: v
            }))
    compile({
        list
    }, './src/router.js'.'./template/router.js.hbs')

    // Generate a menu
    compile({
        list
    }, './src/App.vue'.'./template/App.vue.hbs')



    / * * * *@param {*} meta 
     * @param {*} filePath 
     * @param {*} templatePath 
     */
    function compile(meta, filePath, templatePath) {
        if (fs.existsSync(templatePath)) {
            const content = fs.readFileSync(templatePath).toString()
            const reslut = handlebars.compile(content)(meta)
            fs.writeFileSync(filePath, reslut)
        }
        console.log(chalk.red(` 🚀${filePath}Create success '))}}Copy the code

Publish code to NPM

./publish.sh

#!/usr/NPM config set registry= HTTP://registry.npmjs.org
echo 'Please perform login related operations :'NPM login # echo"-------publishing-------"NPM publish # config set registry= HTTPS:/ / registry.npm.taobao.org # set to taobao mirror echo "issued to complete"
exit
Copy the code

Run sh. /publish.sh