• Node项目模板管理脚手架ptm-cli开发


    一、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: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、知识储备

    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 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(`
    添加模板失败:${err}
    `));
          } else {
            console.log(chalk.green("
    添加模板成功!
    "));
            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("当前模板不存在!
    "));
      return;
    }
    if (!projectName) {
      console.log(chalk.red("新建项目名不能为空! 
    "));
      return;
    }
    
    let temp = tpConfig[templateName];
    //提取模板的url
    let url = temp.url;
    //提取分支
    let branch = temp.branch;
    
    console.log(chalk.greenBright("
    开始创建项目~ 
    "));
    //显示加载图标
    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(`
    创建项目失败:${err}
    `));
      } else {
        if (temp.deldelGitInfo) {
          // 删除.git相关文件
          rm(projectName + "/.git");
        }
    
        //成功
        spinner.succeed();
        console.log(chalk.green("
    项目创建成功~ 
    "));
        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包,安装完执行自定义命令有效!

  • 相关阅读:
    Java学习笔记-函数
    Java学习笔记-数组
    Git 常用命令速查表
    $.fn与$.fx什么意思; $.extend与$.fn.extend用法区别; $(function(){})和(function(){})(jQuery)
    offsetWidth的bug
    jQuery对象和DOM对象转换,解决jQuery对象不能使用js方法的问题
    1
    $().ready()与window.onload的不同
    offsetHeight在不同的浏览器下取值不同
    getElementsByName兼容ie 但并不是兼容ie下的所有标签
  • 原文地址:https://www.cnblogs.com/wawoweb/p/14196672.html
Copyright © 2020-2023  润新知