項目模板管理腳手架ptm-cli開發

1、ptm-cli 使用說明

  project template manager clijavascript

  一款對項目模板/項目進行管理的腳手架工具,具備添加模板/項目編輯模板/項目刪除模板/項目查看模板/項目以及下載項目根據模板初始化項目等功能。vue

一、特色

  • ptm-cli兼容githubgitee碼雲

    如今不少自行開發的腳手架都是都只能對github上模板/項目進行下載(底層使用download-git-repo),隨着國內碼雲的發展壯大,國內開發者不少也在碼雲上進行代碼管理,兼容gitee也十分必要;目前現有的腳手架輪子中並無兼容碼雲的!java

  • 管理功能全

    大多數腳手架只對某一個模板進行初始化下載,只具有指定初始化功能;ptm-cli可以對模板和項目進行管理,不只能夠自由添加刪除開源的優秀項目(例如vue),還能夠添加刪除編輯本身開發的項目模板node

二、安裝

$ npm install ptm-cli -g

三、使用

1)基礎幫助命令

安裝完在電腦終端輸入相應命令查看和執行相關操做。git

# 查看腳手架可執行的相關命令語句
$ ptm 

# 查看當前版本
$ ptm -V

# 查看幫助
$ ptm -h

2)添加模板/項目

輸入命令:github

$ ptm-add

根據終端提示輸入相關信息:web

模板名:添加的模板 自定義命名(建議使用引文);

url:模板/項目在github或者碼雲上的https/ssh克隆地址連接;shell

branch:模板/項目所在github或者碼雲上的分支名(默認master);npm

delGitInfo是否刪除模板/項目中的原做者git的開發信息(默認true刪除),對於模板管理建議默認設置爲true,即初始化模板不含有其餘讓人的git信息,對於項目管理(本身項目)建議保留本身開發相關的git信息;json

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:true
xxx %

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:false
xxx %

4)查看模板/項目

輸入命令:

$ ptm-list

例子:

xxx % ptm-list

模板列表爲:
   vpblogs
     url:git@gitee.com:goodloving/vpblogs.git
     branch:master
     description:基於vuepress建立我的博客主頁的模板工程
     delGitInfo:false
xxx %

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)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

二、初始化項目

  新建項目文件夾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,項目目錄結構以下:

image.png

三、功能開發

  在上述新建bin目錄下的6個功能文件最上方添加#!/usr/bin/env node:配置#!/usr/bin/env node, 就是解決了不一樣系統node路徑不一樣,讓系統動態的去查找node來執行你的腳本文件。

1)ptm(腳手架命令提示)

分析:

  當用戶不瞭解ptm-cli時,輸入ptm能夠向用戶展現可用的所用命令語句和含義(commander);

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

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 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("開始你的項目開發!"));
  }
});

四、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包,安裝完執行自定義命令有效!

相關文章
相關標籤/搜索