首页 > 其他 > nodejs发布一个cli脚手架

nodejs发布一个cli脚手架

创建一个工程:

// 配置工程常用基础工具库
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

给工程配置全局软连接,这里使用kkb命令

# vue-auto-router-cli/bin/kkb.js
#指定脚本解释器为node
#!/usr/bin/env node
console.log('cli.....')
#---------------------------------
# vue-auto-router-cli/package.json
"bin": {
"kkb": "./bin/kkb.js"
},
#---------------------------------
# 将npm 模块链接到对应的运行项目中去
# 在这个目录(vue-auto-router-cli)执行一下命令,上面配置的kkb命令就会在全局创建一个软连接。使得kkb可以在任何目录使用
npm link
# 删除的情况
ls /usr/local/bin/
rm /usr/local/bin/kkb

以下是完整代码:

// vue-auto-router-cli/bin/kkb.js
#!/usr/bin/env node
const program = require('commander')
program.version(require('../package.json').version)
program.command('init ')
      .description('init project')
      // action接收一个回调函数,入参是命令name, 例如kkb init 
      .action(require('../lib/init'))
program
.command('refresh')
.description('refresh routers...')
.action(require('../lib/refresh'))

// 这句很重要,代表所有要执行命令 init name
program.parse(process.argv)

// vue-auto-router-cli/lib/init.js
const {promisify} = require('util')
const figlet = promisify(require('figlet'))

const clear = require('clear')
const chalk = require('chalk')

const log = content => console.log(chalk.green(content))
const {clone} = require('./download')

const spawn = async (...args) => {
  const {spawn} = require('child_process')
  const options = args[args.length - 1]
  if(process.platform === 'win32'){
      // 设置 shell 选项为 true 以隐式地调用 cmd 
      options.shell = true
  }else {
      // nothing
  }
  return new Promise(resolve => {
    const proc = spawn(...args)
    proc.stdout.pipe(process.stdout)
    proc.stderr.pipe(process.stderr)
    proc.on('close', () => {
      resolve()
    })
  })
}

module.exports = async name => {
  // 打印欢迎界面
  clear()
  const data = await figlet('KKB Welcome')
  log(data)
  log(`创建项目:${name}`)
  // 初始化
  await clone('github:allen******/vue-template', name)
  // 安装依赖
  // log('安装依赖...')
  // await spawn('cnpm', ['install'], {cwd: `./${name}`})
  // log(`
  //     安装完成:
  //     To get Start:
  //     ===========================
  //     cd ${name}
  //     npm run serve
  //     ===========================
  // }`)
  // // 打开浏览器
  // const open = require("open")
  // // 启动服务
  // await spawn('npm', ['run', 'serve'], {cwd: `./${name}`})
}
// vue-auto-router-cli/lib/download.js
const {promisify} = require('util')
module.exports.clone = async function (repo, desc) {
  const download = promisify(require('download-git-repo'))
  const ora = require('ora')
  const process = ora(`下载...${repo}`)
  process.start()
  await download(repo, desc)
  process.succeed()
}
// 这个工具通过view模板名称自动生成路由表和路由链接
// vue-auto-router-cli/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(v => v !== 'Home.vue')
      .map(v => ({
        name: v.replace('.vue', '').toLowerCase(),
        file: v
      }))

  // 编译路由
  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}创建成功`)
    }
  }
}
// test/template/App.vue.hbs




// test/template/router.js.hbs
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'

Vue.use(Router)

export default new Router({
  mode: 'history',
  base: process.env.BASE_URL,
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {{#each list}}
    {
      path: '/{{name}}',
      name: '{{name}}',
      component: () => import('./views/{{file}}')
    },
    {{/each}}
  ]
})

评论区

粤ICP备15040393号-1