1.0.1 • Published 4 years ago

test-cli-a v1.0.1

Weekly downloads
1
License
ISC
Repository
-
Last release
4 years ago

从 0 开始搭建简单的脚手脚

对于团队来说,搭建一个适用于公司的脚手架非常有用,可以实现统一的代码风格、全局请求封装、全局错误处理、公共的工具类函数、UI 组件、统一的构建命令等。 当新项目启动时,通过脚手架命令快速搭建一个基础框架,然后就开始进行具体的业务开发,有效的提升工作效率。

初始化项目

mkdir my-test-cli
cd my-test-cli
npm init

安装依赖插件

名称说明
commander可以解析用户输入的命令与参数
download-git-repo下载 git 仓库的项目模板
inquirer命令行用户界面集合,用于和用户进行交互
handlebars模板引擎,将用户提交的信息动态填充到文件
ora用于显示下载中的动画效果
chalk给终端字体加上颜色
log-symbols在终端上显示 √ 或 × 等的图标
安装插件
npm i commander --save
npm i download-git-repo --save
npm i inquirer --save
npm i handlebars --save
npm i ora --save
npm i chalk --save
npm i log-symbols --save

修改 package.json 文件

"bin": {
  "my-test-cli": "./index.js"
}

作用是可以在命令里输入 my-test-cli,然后会执行./index.js 里的代码

新建 index.js 文件

内容如下

#! /usr/bin/env node
console.log("hello word");

说明

#! /usr/bin/env node 指定这个文件使用 node 执行

运行 npm link 命令,将 npm 包链接到全局环境

npm link 然后运行 my-test-cli 之后会输出 hello word

实现输出版本号命令 my-test-cli -v

修改 index.js 文件

#! /usr/bin/env node
const cmd = require("commander");
const pk = require("./package");
cmd.version(pk.version, "-v,--version");
cmd.parse(process.argv);

执行命令 my-test-cli -v 之后会输出版本号

实现带参数的命令 my-test-cli init param1 param2

修改 index.js 文件

const cmd = require("commander");
const pk = require("./package");
const chalk = require("chalk");
cmd.version(pk.version, "-v,--version");
cmd.command("init <name> [age]").action((name, age) => {
  console.log(chalk.green(name));
  console.log(chalk.green(age));
});
cmd.parse(process.argv);

运行命令 my-test-cli init aa,会输出 aa

从 githut 或 gitlap 下载模板文件

githut 指定地址下载 const download = require('download-git-repo'); download(repository, destination, options, callback)

repositiory 仓库
  GitHub - github:owner/name or simply owner/name
  GitLab - gitlab:owner/name
  Bitbucket - bitbucket:owner/name
  Direct - direct:url
destination 下载到指定目录,如 'a' | 'a/b/c'
options
  clone
  proxy
  headers
  filter
#! /usr/bin/env node
const cmd = require("commander");
const pk = require("./package");
const chalk = require("chalk");
const download = require("download-git-repo");
const ora = require("ora");
const logSymbol = require("log-symbols");
cmd.version(pk.version, "-v,--version");
cmd.command("init").action(() => {
  let folder = process.cwd() + "/a"; // process.cwd() 当前 Node.js 进程执行时的工作目录
  const dp = ora("正在下载文件...");
  dp.start();
  // 根据git地址直接下载文件所当前目录
  download(
    "direct:http://172.16.10.111/yuweixian/test-cli-template.git#master",
    folder,
    { clone: true },
    function(err) {
      if (err) {
        dp.fail();
        console.log(logSymbol.error, chalk.red(err));
      } else {
        dp.succeed();
        console.log(logSymbol.success, chalk.green("下载完成"));
      }
      process.exit();
    }
  );
});
cmd.parse(process.argv);

运行命令 my-test-cli init,之后会下载 git 上的项目版本

动态修改模板 package.json 里的配置,修改 index.js

#! /usr/bin/env node
const cmd = require("commander");
const pk = require("./package");
const chalk = require("chalk");
const download = require("download-git-repo");
const ora = require("ora");
const logSymbol = require("log-symbols");
const inquirer = require("inquirer");
const fs = require("fs");
const handlebars = require("handlebars");

//git模板下载后存放的目录
//process.cwd() 当前Node.js进程执行时的工作目录
const downloadGitFolder = process.cwd() + "/a";

// 获取用户输入的答案
const getUserAnser = () => {
  return inquirer.prompt([
    {
      type: "input",
      name: "name",
      message: "请输入项目名称:"
    },
    {
      type: "input",
      name: "description",
      message: "请输入项目描述:"
    },
    {
      type: "input",
      name: "version",
      message: "请输入版本号:"
    }
  ]);
};

// 从git上下载模板
const downloadGitTemplate = () => {
  return new Promise((resolve, reject) => {
    const dp = ora("正在下载文件...");
    dp.start();
    // 根据github地址直接下载文件
    download(
      "direct:http://172.16.10.111/yuweixian/test-cli-template.git#master",
      downloadGitFolder,
      { clone: true },
      function(err) {
        if (err) {
          dp.fail();
          console.log(logSymbol.error, chalk.red(err));
          reject(false);
        } else {
          dp.succeed();
          console.log(logSymbol.success, chalk.green("下载完成"));
          resolve(true);
        }
      }
    );
  });
};

// 修改webpack文件
const updatePackage = (answers, callback) => {
  let filePath = downloadGitFolder + "/package.json";
  let content = fs.readFileSync(filePath).toString();
  let meta = {
    name: answers.name,
    description: answers.description,
    version: answers.version
  };
  let result = handlebars.compile(content)(meta);
  fs.writeFile(filePath, result, err => {
    if (err) {
      console.log(chalk.red(err));
    } else {
      console.log(chalk.green("修改模板package.json文件成功"));
    }
    if (callback && callback instanceof Function) {
      callback();
    }
  });
};

cmd.version(pk.version, "-v,--version");
cmd.command("init").action(async () => {
  // 获取用户的输入内容
  let answers = await getUserAnser();
  // 下载git模板
  let downloadFinished = await downloadGitTemplate();
  if (downloadFinished) {
    // 更新package文件
    updatePackage(answers, () => {
      process.exit();
    });
  }
});

cmd.parse(process.argv);

用一个新目录来测试命令

去掉 'a' 测试目录,最终为

const downloadGitFolder = process.cwd() + "/";

发布到 npm

  1. 注册 npm 账号
  2. 所在目录运行 npm login npm publish

注意,如果设置了淘宝镜像,npm login 的时候可能会出错 这时就需把镜像设置回来 npm config set registry http://registry.npm.taobao.org/ 再重试

其他 npm install -g cnpm --registry=https://registry.npm.taobao.org

最后,分享评价,请扫码

npm.io