一、ptm-cli 应用阐明

  project template manager cli

  一款对我的项目模板/我的项目进行治理的脚手架工具,具备增加模板/我的项目编辑模板/我的项目删除模板/我的项目查看模板/我的项目以及下载我的项目依据模板初始化我的项目等性能。

1、特点

  • ptm-cli兼容githubgitee码云

    当初很多自行开发的脚手架都是都只能对github上模板/我的项目进行下载(底层应用download-git-repo),随着国内码云的发展壮大,国内开发者很多也在码云上进行代码治理,兼容gitee也十分必要;目前现有的脚手架轮子中并没有兼容码云的!

  • 治理性能全

    大多数脚手架只对某一个模板进行初始化下载,只具备指定初始化性能;ptm-cli可能对模板和我的项目进行治理,不仅能够自由增加删除开源的优良我的项目(例如vue),还能够增加删除编辑本人开发的我的项目模板

2、装置

$ npm install ptm-cli -g

3、应用

1)根底帮忙命令

装置完在电脑终端输出相应命令查看和执行相干操作。

# 查看脚手架可执行的相干命令语句$ ptm # 查看以后版本$ ptm -V# 查看帮忙$ ptm -h

2)增加模板/我的项目

输出命令:

$ ptm-add

依据终端提醒输出相干信息:

模板名:增加的模板自定义命名(倡议应用引文);

url:模板/我的项目在github或者码云上的https/ssh克隆地址链接;

branch:模板/我的项目所在github或者码云上的分支名(默认master);

delGitInfo是否删除模板/我的项目中的原作者git的开发信息(默认true删除),对于模板治理倡议默认设置为true,即初始化模板不含有其余让人的git信息,对于项目管理(本人我的项目)倡议保留本人开发相干的git信息;

description:模板/我的项目的形容信息(默认为空);

例子:

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:truexxx % 

3)编辑模板/我的项目

输出命令:

$ ptm-edit templateName key content

依据终端提醒输出相干信息:

templateName:自己增加过的模板/我的项目名

key:想要进行编辑的模板/我的项目的要害信息,包含:urlbranchdelGitInfodescription

content:对关键字对应内容进行编辑代替的内容;

例子(批改模板vpblogs的delGitInfo信息):

xxx % ptm-edit vpblogs delGitInfo false批改模板胜利!最终的模板列表为:   vpblogs     url:git@gitee.com:goodloving/vpblogs.git     branch:master     description:基于vuepress创立集体博客主页的模板工程     delGitInfo:falsexxx % 

4)查看模板/我的项目

输出命令:

$ ptm-list

例子:

xxx % ptm-list模板列表为:   vpblogs     url:git@gitee.com:goodloving/vpblogs.git     branch:master     description:基于vuepress创立集体博客主页的模板工程     delGitInfo:falsexxx % 

5)删除模板/我的项目

输出命令:

$ ptm-del

例子:

xxx % ptm-del? 请输出要删除的模板名称 vpblogs删除模板胜利!最终的模板列表为:xxx % 

6)基于模板新建/初始化我的项目

输出命令:

$ ptm-init vpblogs testPTM

例子(依据模板vpblogs新建我的项目testPTM):

xxx % ptm-init vpblogs testPTM开始创立我的项目~ ✔ 正在创立中···我的项目创立胜利~ 开始你的我的项目开发!xxx % 

执行实现后在以后终端所在目录下能够看到名为testPTM的我的项目文件!

ptm-cli 脚手架开发

1、常识储备

1)commander

残缺的 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);
  • ···

commander具体api

2)inquirer

解决可交互的node.js嵌入式的命令行界面的第三方npm库。

罕用API:

  • 申明 inquirer 变量
const inquirer = require('inquirer');
  • 具体应用形式
inquirer
.prompt([
/ 放入可交互式提供的问题 /
])
.then(answers => {
// 命令行中接管到的输出参数
})
.catch(error => {
// 报错获取
});
  • ···

inquirer具体api

3)git-clone

通过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: 切换到以后分支(可选).

git-clone具体api

4)chalk

扭转终端输入款式的第三方npm库。

罕用API:

  • 申明 chalk 变量
const chalk = require('chalk');
  • 具体应用形式
console.log(chalk.blue('Hello world!'));

chalk具体api

5)ora

增加优雅的终端转轮的第三方npm库。

罕用API:

  • 申明 ora 变量
const ora = require('ora');
  • 具体应用形式
const spinner = ora('提醒内容···');
  • 开始显示转轮
spinner.start()
  • 谬误/失败显示转轮
spinner.fail()
  • 胜利转轮显示
spinner.succeed()
  • ···

ora具体api

6)rimraf

封装rm -rf命令,用来删除文件和文件夹的第三方npm库。

罕用API:

  • 申明 rimraf 变量
const rm = require("rimraf").sync;
  • 具体应用形式,删除指定file文件/文件夹
rm(file, [opts], callback)
  • ···

rimraf具体api

2、初始化我的项目

  新建我的项目文件夹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,我的项目目录构造如下:

3、性能开发

  在上述新建bin目录下的6个性能文件最上方增加#!/usr/bin/env node:配置#!/usr/bin/env node, 就是解决了不同零碎node门路不同,让零碎动静的去查找node来执行你的脚本文件。

1)ptm(脚手架命令提醒)

剖析:

  当用户不理解ptm-cli时,输出ptm能够向用户展现可用的所用命令语句和含意(commander);

代码(ptm.js):
#!/usr/bin/env nodeconst 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);

2)ptm-add(增加模板)

剖析:

  将用户指定模板增加到template.json中存储起来,须要与用户进行交互(inquirer),波及到文件的读写(fs),将执行后果向用户展现(chalk);

代码(ptm-add.js):
#!/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};

3)ptm-list、ptm-del、ptm-edit

剖析:
  • ptm-list:读取template.json文件(fs),对json格局数据输入打印(chalk);
  • ptm-del:读取template.json文件(fs),与用户交互(inquirer),删除指定模板信息,输入删除后后果(chalk)
  • ptm-edit:读取template.json文件(fs),与用户交互(inquirer),指定模板的信息进行批改(commander),输入最终批改后果(chalk);

代码简略(省略)

4)ptm-init(依据模板初始化我的项目)

剖析:

  提醒用户ptm-init命令必须的参数设置,对输出参数进行判断,读取template.json信息提取新建我的项目基于的模板信息,从github或者gitee(码云)clone git库文件,依据配置中要求判断是否删除原作者的git开发信息,输入init后果

代码

ptm-init.js

#!/usr/bin/env nodeconst 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];//提取模板的urllet 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("开始你的我的项目开发!"));  }});

4、npm公布

  • 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包,装置完执行自定义命令无效!