搭建 CLI 工具

搭建 CLI 工具

创建工程

mkdir wangyong-cli
cd wangyong-cli
npm init -y

安装依赖:

npm i commander download-git-repo ora handlebars figlet clear chalk open -s
  • bin/index.js

  • 指定脚本编译器为node

#!/usr/bin/env node
console.log('测试 完成')

package.js

"bin": {
	"wy-cli": "./bin/index.js"
}

将npm 模块链接到对应的运行项目中去

npm link

npm link后会把我们的bin/index.js 放到全局,可以在命令窗口直接 wy-cli 执行 文件

wy-cli
测试 完成

定制命令⾏界⾯

bin/index.js

#!/usr/bin/env node
const program = require('commander')
program.version(require('../package').version)
program
 .command('init <name>') // 自定义执行的命令
 .description('init project') // 命令描述
 .action(name => { //执行命令后所执行的方法
 console.log('init ' + name)
})
// 解析命令行参数,注意这个方法一定要放到最后调用
program.parse(process.argv)

我们来测试一下:

wy-cli init project
# 输出
init :project

打印欢迎界面

/lib/init.js

const { promisify } = require('util')// promisify 把原来的异步回调方法改成返回 Promise 实例的方法
const figlet =  promisify(require('figlet')) // 创建艺术文字
const clear = require('clear') // 清空控制台
const chalk = require('chalk') // 字体颜色
const log = content => console.log(chalk.green(content))
module.exports = async name => {
  // 打印欢迎画面
  clear()
  const data = await figlet(`wy-cli welcome`)
  log(data)
}

/bin/index.js

#!/usr/bin/env node
const program = require('commander')
// 设置版本
program.version(require('../package.json').version)
program
  .command('init <name>')
  .description('init project')
  .action(require('../lib/init')) // 引入init 方法
program.parse(process.argv)

克隆脚手架

/lib/download.js

const { promisify } = require('util')
module.exports.clone = async function(repo, desc) {
  const dowload = promisify(require('download-git-repo')) // 从node下载并解压一个git存储库(GitHub, GitLab, Bitbucket)。
  const ora = require('ora')
  const loading = ora(`下载.... ${repo}`)// 加载动画
  loading.start()
  await dowload(repo, desc) // 从github克隆项⽬到指定⽂件夹
  loading.succeed()
}

/lib/init.js

const { clone } = require('./download')
module.exports = async name => {
  // 打印欢迎画面
  clear()
  const data = await figlet(`wy-cli welcome`)
  log(data)
  log(`🚀 创建项目:${name}`)
  // 从github 克隆项目到指定文件夹
  await clone('github:wangyong1997/wy-cli', name)
}

安装依赖

/lib/init.js

// promisiy化spawn
// 对接输出流
async function spawn (...args) {
  const { spawn } = requiire('child_process')
  return new Promise(resolve => {
    const proc = spawn(...args)
    // 表示子进程的 stdout 的可读流。
    // process.stdout 属性返回连接到 stdout (fd 1) 的流。 它是一个 net.Socket 流(也就是双工流),除非 fd 1 指向一个文件,在这种情况下它是一个可写流
    proc.stdout.pipe(process.stdout)
    // process.stderr 属性返回连接到 stderr (fd 2) 的流。 它是一个 net.Socket 流(也就是双工流),除非 fd 2 指向一个文件,在这种情况下它是一个可写流。
    proc.stderr.pipe(process.stderr)
    proc.on('close', ()=> {
      resolve()
    })
  })
}
module.exports = async name => {
  // 打印欢迎画面
  clear()
  const data = await figlet(`wy-cli welcome`)
  log(data)
  log(`🚀 创建项目:${name}`)
  // 从github 克隆项目到指定文件夹
  await clone('github:wangyong1997/wy-cli', name)
  log('安装依赖')
  await spawn('cnpm', ['install'], {cwd: `./${name}`})
  log(`
🆗 安装完成:
To get Start:
===========================
cd ${name}
npm run serve
===========================
  `)
}

发布 npm

publish.sh

#!/usr/bin/env bash
npm config get registry # 检查仓库镜像库
npm config set registry=http://registry.npmjs.org
echo '请进⾏登录相关操作:'
npm login # 登陆
echo "-------publishing-------"
npm publish # 发布
npm config set registry=https://registry.npm.taobao.org # 设置为淘宝镜像
echo "发布完成"
exit

补充: 我们还可以让项目自动启动,自动打开浏览器:

const open = require('open') // 打开浏览器
module.exports = async name => {
  // ...
  // 启动项目
  await spawn('npm', ['run', 'serve'], {cwd: `./${name}`})
  // 打开浏览器
  open('http://localhost:8080');
}
posted @ 2020-08-26 17:09  渡心°  阅读(380)  评论(0编辑  收藏  举报