创建CLI工程
mkdir cli-demo
cd cli-demo
npm init -y
npm i commander download-git-repo ora handlebars figlet clear chalk open -s
#bin/cui.js
#指定脚本解释器为node
#!/usr/bin/env node
# package.json
"bin": {
"cui": "./bin/cui.js"
}
#将npm模块链接到对应的运行项目中去
npm link
# 删除link
ls /usr/local/bin/
rm /usr/local/bin/cui
定制命令行界面
#!/usr/bin/env node
const program = require("commander");
program.version(require("../package.json").version);
program
.command("init <name>")
.description("init project")
.action(require(name => {
console.log(\'init\' + name)
});
program.parse(process.argv);
打印欢迎界面
// 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));
module.exports = async (name) => {
// 打印欢迎界面
clear();
const data = await figlet("Cui Welcome");
log(data);
};
// bin/cui.js
program
.command("init <name>")
.description("init project")
.action(require("../lib/init"));
克隆脚手架
// lib/download.js
const { promisify } = require("util");
module.exports.clone = async (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();
};
// lib/init.js
const { clone } = require("./download");
module.exports = async (name) => {
log("创建项目:" + name);
await clone("github:su37josephxia/vue-template", name);
};
安装依赖
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) => {
//...
log("安装依赖");
await spawn("npm", ["install"], { cwd: `./${name}` });
log(
chalk.green(`
安装完成:
To get start:
==============================
cd ${name}
npm run serve
==============================
`)
);
};
启动项目
const open = require("open");
module.exports = async (name) => {
//...
open("http://localhost:8080");
await spawn("npm", ["run", "serve"], { cwd: `./${name}` });
};
约定路由功能
- loader文件扫描
- 代码模板渲染 hbs Mustache风格模板
// lib/refresh.js
const fs = require("fs");
const handlebars = require("handlebars");
const chalk = require("chalk");
const path = require("path");
module.exports = async () => {
const list = fs
.readdirSync(path.resolve("./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");
};
// 编译模板文件
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(chalk.green(`${filePath}创建成功`));
}
// bin/cui
program
.command("refresh")
.description("refresh routers...")
.action(require("../lib/refresh"));
发布npm
#!/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 "发布完成"