project template manager cli
javascript
一款对项目模板/项目进行管理的脚手架工具,具备添加模板/项目
、编辑模板/项目
、删除模板/项目
、查看模板/项目
以及下载项目
和根据模板初始化项目
等功能。vue
github
和gitee码云
:如今不少自行开发的脚手架都是都只能对github上模板/项目进行下载(底层使用download-git-repo
),随着国内码云的发展壮大,国内开发者不少也在码云上进行代码管理,兼容gitee也十分必要;目前现有的脚手架轮子中并无兼容码云的!java
大多数脚手架只对某一个模板进行初始化下载,只具有指定初始化功能;ptm-cli可以对模板和项目进行管理
,不只能够自由添加删除开源的优秀项目
(例如vue),还能够添加删除编辑本身开发的项目模板
;node
$ npm install ptm-cli -g
安装完在电脑终端输入相应命令查看和执行相关操做。git
# 查看脚手架可执行的相关命令语句 $ ptm # 查看当前版本 $ ptm -V # 查看帮助 $ ptm -h
输入命令:github
$ ptm-add
根据终端提示输入相关信息:web
模板名:添加的模板自定义命名
(建议使用引文);url:模板/项目在
github
或者码云
上的https
/ssh
克隆地址连接;shellbranch:模板/项目所在github或者码云上的
分支名
(默认master);npmdelGitInfo:是否删除模板/项目中的
原做者git的开发信息
(默认true删除),对于模板管理建议默认设置为true,即初始化模板不含有其余让人的git信息,对于项目管理(本身项目)建议保留本身开发相关的git信息;jsondescription:模板/项目的描述信息(默认为空);
例子:
xxx % ptm-add ? 请输入模板名称 vpblogs ? 请输入模板地址(https/ssh) git@gitee.com:goodloving/vpblogs.git ? 请输入模板分支(默认master) master ? 是否删除模板中.git信息(默认删除) true ? 请输入模板描述(默认为空) 基于vuepress建立我的博客主页的模板工程 添加模板成功! 最终的模板列表为: vpblogs url:git@gitee.com:goodloving/vpblogs.git branch:master description:基于vuepress建立我的博客主页的模板工程 delGitInfo:true xxx %
输入命令:
$ ptm-edit templateName key content
根据终端提示输入相关信息:
templateName:本人添加过的模板/项目名
;key:想要进行编辑的模板/项目的
关键信息
,包括:url、branch、delGitInfo、description;content:对关键字对应
内容进行编辑替代
的内容;
例子(修改模板vpblogs的delGitInfo信息):
xxx % ptm-edit vpblogs delGitInfo false 修改模板成功! 最终的模板列表为: vpblogs url:git@gitee.com:goodloving/vpblogs.git branch:master description:基于vuepress建立我的博客主页的模板工程 delGitInfo:false xxx %
输入命令:
$ ptm-list
例子:
xxx % ptm-list 模板列表为: vpblogs url:git@gitee.com:goodloving/vpblogs.git branch:master description:基于vuepress建立我的博客主页的模板工程 delGitInfo:false xxx %
输入命令:
$ ptm-del
例子:
xxx % ptm-del ? 请输入要删除的模板名称 vpblogs 删除模板成功! 最终的模板列表为: xxx %
输入命令:
$ ptm-init vpblogs testPTM
例子(根据模板vpblogs新建项目testPTM):
xxx % ptm-init vpblogs testPTM 开始建立项目~ ✔ 正在建立中··· 项目建立成功~ 开始你的项目开发! xxx %
执行完成后在当前终端所在目录
下能够看到名为testPTM
的项目文件!
ptm-cli
脚手架开发完整的 node.js 命令行解决方案
,用来处理终端命令行中输入命令和编写命令行指令的第三方npm库。
经常使用API:
- 声明 program 变量
const { program } = require('commander');
- 命令行输出版本号
program.version('0.0.1');
- 命令行输出指令提示
program.usage("\<command> [Options]");
- 命令行输出单一命令输入规范提示
program.command("ptm-add", "新增一个模板库!")
- 解析命令行参数
program.parse(process.argv);
- ···
处理可交互
的node.js嵌入式的命令行界面
的第三方npm库。
经常使用API:
- 声明 inquirer 变量
const inquirer = require('inquirer');
- 具体使用方式
inquirer
.prompt([
/ 放入可交互式提供的问题 /
])
.then(answers => {
// 命令行中接收到的输入参数
})
.catch(error => {
// 报错获取
});
- ···
经过shell命令克隆
一个git存储库
的第三方npm库。
经常使用API:
- 声明 git-clone 变量
const clone = require('git-clone');
- 具体使用方式
clone(repo, targetPath, [options], cb);
克隆一个repo路径的git仓库到targetPath目录下,回调函数cd用来捕捉克隆结果;
- options可选参数:
- git: git的二进制路径(可选).
- shallow: 当为true时克隆深度为1 (可选).
- checkout: 切换到当前分支(可选).
改变终端输出样式
的第三方npm库。
经常使用API:
- 声明 chalk 变量
const chalk = require('chalk');
- 具体使用方式
console.log(chalk.blue('Hello world!'));
添加优雅的终端转轮
的第三方npm库。
经常使用API:
- 声明 ora 变量
const ora = require('ora');
- 具体使用方式
const spinner = ora('提示内容···');
- 开始显示转轮
spinner.start()
- 错误/失败显示转轮
spinner.fail()
- 成功转轮显示
spinner.succeed()
- ···
封装rm -rf
命令,用来删除文件和文件夹
的第三方npm库。
经常使用API:
- 声明 rimraf 变量
const rm = require("rimraf").sync;
- 具体使用方式,删除指定file文件/文件夹
rm(file, [opts], callback)
- ···
新建项目文件夹PTM_CLI
,在项目文件夹下打开终端执行初始化操做npm init
,与终端进行交互操做生成含有项目信息的package.json
文件,依次安装步骤1
中的6个
要用到的第三方npm库:npm install xxx -g
(也可直接将依赖写入package.json
中的dependences
中,直接执行npm install
);
打开package.json
文件,添加终端命令执行语句(bin
区域下):
{ "name": "ptm-cli", ··· "private": false, "author": { "name": "wawoweb", "wechat(公众号)": "wawoweb / 哇喔WEB", "wechat": "h17179797429", "email": "936106161@qq.com" }, "bin": { "ptm": "./bin/ptm.js", "ptm-init": "./bin/ptm-init.js", "ptm-list": "./bin/ptm-list.js", "ptm-add": "./bin/ptm-add.js", "ptm-del": "./bin/ptm-del.js", "ptm-edit": "./bin/ptm-edit.js" }, ··· "dependencies": { "chalk": "^4.1.0", "commander": "^6.2.1", "git-clone": "^0.1.0", "inquirer": "^7.3.3", "ora": "^5.1.0", "rimraf": "^3.0.2" } }
同时,在项目文件夹下新建目录bin
,并在bin文件夹下新建package.json
中对应的6个文件:
./bin/ptm.js 终端命令ptm执行文件 ./bin/ptm-init.js 终端命令ptm-init执行文件(根据模板初始化项目) ./bin/ptm-list.js 终端命令ptm-list执行文件(查看当前模板列表) ./bin/ptm-add.js 终端命令ptm-add执行文件(添加新的模板) ./bin/ptm-del.js 终端命令ptm-del执行文件(删除指定模板) ./bin/ptm-edit.js 终端命令ptm-edit执行文件(编辑指定模板指定信息内容)
最后在根目录下新建模板存储文件template.json
,项目目录结构以下:
在上述新建bin目录
下的6个功能文件
最上方添加#!/usr/bin/env node
:配置#!/usr/bin/env node, 就是解决了不一样系统node路径不一样,让系统动态的去查找node来执行你的脚本文件。
当用户不了解ptm-cli时,输入ptm能够向用户展现可用的所用命令语句和含义(commander
);
#!/usr/bin/env node const program = require("commander"); const package = require("../package.json"); // 定义当前版本 // 定义使用方法 // 定义五个指令 program .version(package.version) .usage("<command> [Options]") .command("ptm-add", "新增一个模板库!") .command("ptm-del", "删除一个模板库!") .command("ptm-list", "查看模板库列表!") .command("ptm-edit templatename key content", "修改模板库信息!") .command("ptm-init templatename projectName", "基于模板库建立一个新的工程!"); // 解析命令行参数 program.parse(process.argv);
将用户指定模板添加到template.json中存储起来,须要与用户进行交互(inquirer
),涉及到文件的读写(fs
),将执行结果向用户展现(chalk
);
#!/usr/bin/env node //交互式命令行库 const inquirer = require("inquirer"); //控制台样式库 const chalk = require("chalk"); //node内置文件模块库 const fs = require("fs"); //读取模板配置文件 const tpConfig = require(`${__dirname}/../template.json`); // 打印模板列表的公共函数 const printPtmList = require("../utils").printPtmList; //自定义交互式命令行的问答 let questions = [ { name: "name", type: "input", message: "请输入模板名称", validate(val) { if (val === "") { return "模板名不能为空!"; } else if (tpConfig[val]) { return "模板名已经存在!"; } else { return true; } }, }, { name: "url", type: "input", message: "请输入模板地址(https/ssh)", validate(val) { if (val === "") return "模板地址不能为空!"; return true; }, }, { name: "branch", type: "input", message: "请输入模板分支(默认master)", default: "master", }, { name: "delGitInfo", type: "input", message: "是否删除模板中.git信息(默认删除)", default: true, }, { name: "description", type: "input", message: "请输入模板描述(默认为空)", default: "", }, ]; inquirer.prompt(questions).then((answers) => { // 获取用户输入的内容 let { name, url, branch, description, delGitInfo } = answers; //过滤Unicode的字符 tpConfig[name] = { url, branch, description, delGitInfo, }; // 将模板信息写入template.json文件中s fs.writeFile( `${__dirname}/../template.json`, JSON.stringify(tpConfig), "utf-8", (err) => { if (err) { console.log(chalk.red(`\n添加模板失败:${err}\n`)); } else { console.log(chalk.green("\n添加模板成功!\n")); console.log("最终的模板列表为:"); printPtmList(tpConfig); } } ); });
模板列表打印函数封装(utils.js):
const chalk = require("chalk"); const printPtmList = (tpConfig) => { //遍历模板展现出来 for (const key in tpConfig) { if (tpConfig.hasOwnProperty(key)) { const item = tpConfig[key]; console.log(chalk.blue(` ${key}`)); for (const i in item) { if (item.hasOwnProperty.call(item, i)) { const el = item[i]; console.log(chalk.blue(` ${i}:${el}`)); } } } } }; module.exports = { printPtmList };
代码简单(省略)
提示用户ptm-init
命令必须的参数设置,对输入参数进行判断
,读取template.json
信息提取新建项目基于的模板信息,从github
或者gitee(码云)
上clone git库
文件,根据配置中要求判断是否删除原做者的git开发信息
,输出init结果
!
ptm-init.js
#!/usr/bin/env node const program = require("commander"); const chalk = require("chalk"); const ora = require("ora"); const gitclone = require("git-clone"); const tpConfig = require(`${__dirname}/../template`); const rm = require("rimraf").sync; program.usage("templatename projectName").parse(process.argv); //判断输入状况 if (program.args.length < 1) { return program.help(); } //输入参数提取 let templateName = program.args[0]; let projectName = program.args[1]; //参数校验 if (!tpConfig[templateName]) { console.log(chalk.red("当前模板不存在!\n")); return; } if (!projectName) { console.log(chalk.red("新建项目名不能为空! \n")); return; } let temp = tpConfig[templateName]; //提取模板的url let url = temp.url; //提取分支 let branch = temp.branch; console.log(chalk.greenBright("\n开始建立项目~ \n")); //显示加载图标 const spinner = ora("正在建立中···"); spinner.start(); //下载所需额外参数 let cloneOptions = { checkout: branch, shallow: branch === "master", }; // 下载git上模板代码 gitclone(url, projectName, cloneOptions, (err) => { if (err) { spinner.fail(); console.log(chalk.red(`\n建立项目失败:${err}\n`)); } else { if (temp.deldelGitInfo) { // 删除.git相关文件 rm(projectName + "/.git"); } //成功 spinner.succeed(); console.log(chalk.green("\n项目建立成功~ \n")); console.log(chalk.green("开始你的项目开发!")); } });
1)确认package.json中npm发布内容是否完善正确
- "name": "ptm-cli", //发布到npm上的库的名字
- "version": "1.0.0", //当前发布版本号(x.y.z格式规定:x大的版本号,大版本号不一样表明不向下兼容;y小版本号,当前版本较大改动,向下兼容;z代码较小改动或者bug修改)
- "description": "", //npm库的简要描述
- "private": false, //是否公开设置
- "keywords": [], //npm上搜索的关键词设置
- ···
2)npm登陆和发布
- 去npm网站注册帐号;
- 终端输入
npm login
,根据提示输入用户名、密码、邮箱;- 终端输入
npm publish
发布,查看结果是否发布成功;- 强制撤回24小时内发布的npm库,输入
npm unpublish --force
;
3)npm发布验证
- 在npm网站搜索中输入发布的npm库名,可以搜索到说明已经发布成功!
- 本地下载验证
打开本地终端输入
npm install ptm-cli -g
下载安装发布的npm包,安装完执行自定义命令有效!