手写一个自己的 cli 并发布到 npm 上
简介:大家平时肯定用过 vue-cli 或者 create-react-app,只需要敲简单的命令行,就可以生成一个完成的项目,非常好用。由于本人所在公司接的项目较多,每次新建新项目都是拷贝以前的项目代码,好麻烦,而且得删除掉好多没用的代码,心累。于是就想着模仿 vue-cli 写一个简单的创建项目的 cli,这样不是就省心省力了嘛。于是说干就干,自己写了一个 cli:va-cli,大家也可以使用,只要执行以下命令就好,如下
npm install va-cli -g
va-cli init project-name
下面是实现步骤
1.项目依赖:(先安装,步骤略)
 "dependencies": {
    "chalk": "^3.0.0",
    "commander": "^4.0.1",
    "download-git-repo": "^3.0.2",
    "inquirer": "^7.0.1",
    "ora": "^4.0.3"
  },
  "devDependencies": {
    "eslint": "^6.8.0",
    "eslint-config-standard": "^14.1.0",
    "eslint-plugin-import": "^2.19.1",
    "eslint-plugin-node": "^11.0.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.1"
  }
2.项目目录结构
3.核心代码
/bin/va-cli (无文件扩展名)
// 告诉执行环境用node来执行
#!/usr/bin/env node
// 添加命令的库
const program = require('commander')
// 拿到package.json 里的版本号
const packageJson = require('../package.json')
const init = require('../lib/init')
//  执行  va-cli -V 会输出版本号
program.version(packageJson.version)
// 添加init命令,简写是i, <name> 是参数  action回调里可以拿到
program
  .command('init <name>')
  .alias('i')
  .description('vue admin 项目初始化工具')
  .action(name => {
    init(name)
  })
// 解析命令行参数
program.parse(process.argv)
lib/clone.js
// node的 util 模块 promisify可以把回调promise化
const { promisify } = require("util");
// 进度显示工具
const ora = require("ora");
// 颜色显示工具
const chalk = require("chalk");
// 下载git 仓库代码工具
const download = promisify(require("download-git-repo"));
/**
 *
 * @param {string} repo 仓库地址
 * @param {string}  dir 文件夹
 * @param {object}  opotions 配置项
 * @return {excel-file}
 */
const clone = async function(repo, dir, opotions = {}) {
  const process = ora(`开始下载 ${chalk.blue(repo)}`);
  process.start();
  process.color = "yellow";
  process.text = `正在下载..... ${chalk.yellow(repo)} `;
  try {
    await download(repo, dir, opotions);
    process.color = "green";
    process.text = `下载成功 ${chalk.green(repo)} `;
    process.succeed();
  } catch (error) {
    process.color = "red";
    process.text = "下载失败";
    process.fail();
  }
};
module.exports = clone;
lib/init.js
const chalk = require("chalk");
// 用户与命令行交互的工具
const Prompt = require("inquirer");
const clone = require("./clone");
// 对应github仓库地址https://github.com/l-x-f/va-cli
// #dev 是值dev分支,不写默认master分支
const remote = "github:l-x-f/admin-template#dev";
const initQuestions = name => [
  {
    type: "confirm",
    name: "isInit",
    message: `确定要在${chalk.green(name)}文件夹下创建项目?`,
    prefix: "?"
  }
];
const init = async name => {
  try {
    const { isInit } = await Prompt.prompt(initQuestions(name));
    if (isInit) {
      await clone(remote, name);
    } else {
      console.log(chalk.red("程序提前结束"));
    }
  } catch (error) {
    console.log(chalk.red(error));
  }
};
module.exports = init;
package.json
重点是 bin 字段的配置
{
  "name": "va-cli",
  "version": "1.0.1",
  "description": "vue admin 项目初始化工具",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "bin": {
    "va-cli": "./bin/va-cli"
  },
  "keywords": ["vue", "vue-cli", "va-cli", "vue admin 项目初始化工具"],
  "author": "xiaofei",
  "license": "MIT",
  "dependencies": {
    "chalk": "^3.0.0",
    "commander": "^4.0.1",
    "download-git-repo": "^3.0.2",
    "inquirer": "^7.0.1",
    "ora": "^4.0.3"
  },
  "devDependencies": {
    "eslint": "^6.8.0",
    "eslint-config-standard": "^14.1.0",
    "eslint-plugin-import": "^2.19.1",
    "eslint-plugin-node": "^11.0.0",
    "eslint-plugin-promise": "^4.2.1",
    "eslint-plugin-standard": "^4.0.1"
  }
}
4.本地测试
在项目根目录下执行 npm link 会把va-cli命令链接到全局
npm unlink va-cli 可以删除掉
执行就可以看到效果
va-cli init project-name
5.发布到 npm 上 (自行注册账号)
项目根目录下新建 publish.sh
#!/usr/bin/env bash
set -e
# 修改npm源地址
npm config get registry
npm config set registry=http://registry.npmjs.org
# 登陆输入自己的npm账号和密码,还有邮箱
echo '登录'
npm login
echo "发布中..."
npm publish
# 改回npm源地址
npm config set registry=https://registry.npm.taobao.org
echo -e "\n发布成功\n"
exit
执行成功后的显示
6.发布完成后测试
npm i -g va-cli
如果没有这个包的话看一下,npm源是不是http://registry.npmjs.org,taobao源同步有时差
7.实现效果
参考链接
1.https://github.com/sindresorhus/ora
2.https://blog.csdn.net/qq_26733915/article/details/80461257
3.https://github.com/vuejs/vue-cli
4.https://github.com/chalk/chalk
来源:CSDN
作者:xiao_fei_blog
链接:https://blog.csdn.net/qq_39953537/article/details/103747370