首先,新建一个vue-auto-router-cli文件夹,cd vue-auto-router-cli然后执行npm init -y初始化一个项目,再把所需要的依赖安装一下
mkdir vue-auto-router-cli
cd vue-auto-router-cli
npm init -y
npm i commander download-git-repo ora handlebars clear chalk open watch -s
在生成的package.json中添加
"bin": {
"rjd": "./bin/index.js"
},
修改后的package.json文件
//package.json
{
"name": "vue-auto-router-cli",
"version": "1.0.0",
"description": "",
"main": "index.js",
"bin": {
"rjd": "./bin/index.js"
},
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
新建bin文件夹,添加index.js,在文件头添加
#!/usr/bin/env node
终端执行npm link将rjd命令绑定,是否绑定成功可以通过在终端执行rjd命令来看index.js(可以在index.js文件中console一下)文件是否执行。
#!/usr/bin/env node
// console.log('cli....');
// 终端工具依赖
const program = require('commander');
// 版本设定,这里取自package.json中的version
program.version(require('../package.json').version);
// rjd init test初始化一个项目
program
.command('init <name>')
.description('init project')
.action(require('../lib/init.js'));
// rjd refresh刷新路由和菜单
program
.command('refresh')
.description('refresh routers and menu ')
.action(require('../lib/refresh.js'));
// 解析命令行参数,注意这个方法一定要放到最后调用
program.parse(process.argv);
新建lib文件夹,并新建download.js, init.js文件
// download.js
/*
* @Descripttion: 下载
* @Author: RJD
* @Date: 2020-06-29 15:18:22
* @LastEditors: RJD
* @LastEditTime: 2020-06-30 10:55:10
*/
const { promisify } = require('util');
module.exports.clone = async (repo, desc) => {
// 从git上下载东西
const download = promisify(require('download-git-repo'));
// ora包用于显示加载中的效果
const ora = require('ora');
const process = ora(`下载......${repo}`);
// 开始加载
process.start();
// 下载资源
await download(repo, desc);
// 加载成功
process.succeed();
}
// init.js
/*
* @Descripttion: 初始化
* @Author: RJD
* @Date: 2020-06-29 16:28:32
* @LastEditors: RJD
* @LastEditTime: 2020-06-30 15:21:21
*/
// node中自带api
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 open = require('open');
const spawn = async (...args) => {
const { spawn } = require('child_process');
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('RJD WELCOME');
// 加载一个欢迎效果
log(data);
// clone
log(`创建项目: ${name}`);
await clone('github:su37josephxia/vue-template', name);
// 自动安装依赖
log('安装依赖');
await spawn('cnpm', ['install'], {cwd: `./${name}`});
log(`
安装完成:
To get start:
=====================
cd ${name}
npm run serve
=====================
`);
// 在默认浏览器中打开http://localhost:8080
open('http://localhost:8080');
// 启动
await spawn('npm', ['run', 'serve'], {cwd: `./${name}`});
}


在lib下新建refresh.js文件
/*
* @Descripttion:
* @Author: RJD
* @Date: 2020-06-30 10:39:43
* @LastEditors: RJD
* @LastEditTime: 2020-06-30 15:20:49
*/
// 读取文件所需依赖包
const fs = require('fs');
// 模板工具
const handlebars = require('handlebars');
// const chalk = require('chalk');
module.exports = async () => {
// 获取views文件夹下的文件列表
const list = fs.readdirSync('./src/views')
.filter(v => v !== 'Home.vue')
.map(v => ({
name: v.replace('.vue', '').toLowerCase(),
file: v
}))
console.log(list);
// 生成路由定义
compile({list}, './src/router.js', './template/router.js.hbs');
// 生成菜单
compile({list}, './src/App.vue', './template/App.vue.hbs');
/**
* @name: 模版编译
* @param {*} meta 数据定义
* @param {*} filePath 目标文件
* @param {*} templatePath 模板文件
* @return:
*/
function compile(meta, filePath, templatePath) {
// 先判断模板路径是否存在
if(fs.existsSync(templatePath)){
// 读取模板路径下的文件,然后toString将二进制流转换为可读文本
const content = fs.readFileSync(templatePath).toString();
// 通过handlebars进行编译
const result = handlebars.compile(content)(meta);
// 利用fs.writeFileSync将结果写入filePath
fs.writeFileSync(filePath, result);
console.log(`${filePath} 创建成功`);
}
}
}
另附模板文件
App.vue.hbs
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link>
{{#each list}}
| <router-link to="/{{name}}">{{name}}</router-link>
{{/each}}
</div>
<router-view/>
</div>
</template>
<style>
#app {
font-family: 'Avenir', Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
</style>
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}}
]
})
至此,在终端执行rjd init test会自动下载项目文件,然后自动执行cnpm install安装项目依赖
rjd init test
在views文件中添加*.vue文件后终端执行rjd refresh自动添加router-link和router
rjd refresh
例如在views中新建一个Contact.vue文件,然后执行rjd refresh.
生成的router.js

生成的App.vue文件

一个简单的cli工具就完成啦,哈哈哈