当前位置: 首页 > 工具软件 > Parse CLI > 使用案例 >

node搭建自定义cli

麹正业
2023-12-01

自定义cli 搭建

本文介绍简单的nodecli的搭建,可以通过简单的cli我们去延伸多功能,深度的自定义cli的搭建,搭建的同时我们还可以去掌握node一些常见的插件和api,这篇文章主要介绍 自动化路由的搭建(简单的路由)。

搭建cli

1.下载需要用到的npm包
npm i chalk clear commander download-git-reop figlet handlebars open ora watch util -D
插件的解释:
chalk 用于控制台的颜色
clear 清空控制台
commander 执行指令界面
download-git-reop git下载项目的插件
figlet 改变控制台输出的文字 或者特殊的字符
handlebars 语义化字符串模板(也可以用template)
open 打开浏览器
ora 优雅的终端加载进度 (下载的时候一定要注意 下载 5.3.0以上的)
watch 监听
util 常见函数的集合(本文用于引出异步编程的函数)
2.搭建cli的基础
创建自定义的cli目录 通过npm init -y 去初始化配置 在package.json中配置我们将要执行的命令和文件

//package.json
{
script:{
.......
},
bin:{
"将要全局执行的命令":执行的文件

}
//eg:
bin:{
"jkqtest":"./bin/cli.js"
}

}

//执行的文件入口

//这句话一定要写在入口文件的开头,并且是固定的格式,代表的是一下的文件将以 node的环境运行,#!usr/bin/env 代表的意思是 程序或在你的环境中去找node的环境然后执行如下的代码
#! /usr/bin/env node
console.log('auto-cli....')

const program = require('commander') //命令行工具
program.version(require('./package.json').version) // 或直接写 '1.0.1'

program
   .command('init <name>') // 定义init命令
   .description('init project')//添加自定的描述
   .action(require('./bin/init.js'))//action中的参数是一个回调函数 回调参数则是控制台输入的数据
//这句话一定要写在末尾,用于解析我们定义的命令 并将node的执行参数代入
program.parse(process.argv)
   //刷新路由指令
   program
   .command('refresh') // 定义init命令
   .description('refresh routers')
   .action(require('./bin/refresh'))

执行命令后 进行的操作

// //引入异步方法
const {promisify} = require('util') // util 是一个Node.js 核心模块,提供常用函数的集合,用于弥补核心JavaScript 的功能 过于精简的不足
const figlet = promisify(require('figlet')) //  util.promisify() 这个方法,方便快捷的把原来的异步回调方法改成返回 Promise 实例的方法

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

const spawns = async (...args) => {
    //引入子进程模块
  const {spawn} = require('child_process')
  return new Promise(resolve => {
      //执行子进程
    const proc = spawn(...args) // 在node.js中执行shell一般用spawn,实现从主进程的输出流连通到子进程的输出流
    proc.stdout.pipe(process.stdout) // 子进程正常流搭到主进程的正常流
    proc.stderr.pipe(process.stderr) // 子进程错误流插到主进程的错误流
    //子进程结束
    proc.on('close', () => {
      resolve()
    })
  })
}

module.exports = async name => {
  // 打印欢迎界面
  clear()
  const data = await figlet('JKQ Welcom') // figlet是把文字变成大字
  log(data);

  // clone
  log(`创建项目: ${name}`);
  ///在github中下载项目  **

> 这里对于gitlab的支持不是很友好  [作者建议都使用github(download-git-repo/issue)](https://gitlab.com/flippidippi/download-git-repo/-/issues/46)

**
  await clone('github:su37josephxia/vue-sample', name)
  log('子进程的方式安装依赖')
  await spawns(process.platform === 'win32' ? 'npm.cmd' : 'npm', ['install'], { cwd: `./${name}` })
  log(`安装完成:To get Start: cd ${name} \n npm run server`)

  // 自动启动项目
  await spawns(process.platform === 'win32' ?'npm.cmd' : 'npm',['run', 'dev'],{cwd: `./${name}`})
}

定义下载的方法


const {promisify} = require('util')
module.exports.clone = async function(repo, desc) {
  const download = promisify(require('download-git-repo')) // download-git-repo: Download and extract a git repository (GitHub, GitLab, Bitbucket)
   
    console.log('正在下载请等待.....')
//   const process = ora(`下载......${repo}`)
//   process.start() // 进度条开始
  await download(repo, desc)
  //  download-git-repo导出的download方法,第一个参数repo是仓库地址,格式有三种:
  // GitHub - github:owner/name or simply owner/name
  // GitLab - gitlab:owner/name
  // Bitbucket - bitbucket:owner/name
//   process.succeed()
console.log('下载完成')
}

执行refresh刷新路由的方式

const fs = require('fs')
const hbs = 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 = hbs.compile(content)(meta)
     //再写入我们的路由文件中即可
     fs.writeFileSync(filePath, result)
     console.log('创建成功');
   }
 }
}

以上就是简单的自动创建cli的小工具,后续可能会添加 view 中添加的文件就会自动的去刷新路由,在进一步就是 会根据view 中的目录然后去进行主子路由的生成等 后续继续更新

 类似资料: