搭建 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');
}