手写一个自己的 cli 并发布到 npm 上

简介:大家平时肯定用过 vue-cli 或者 create-react-app,只需要敲简单的命令行,就可以生成一个完整的项目,非常好用。由于本人所在公司接的项目较多,每次新建新项目都是拷贝以前的项目代码,好麻烦,而且得删除掉好多没用的代码,心累。于是就想着模仿 vue-cli 写一个简单的创建项目的 cli,这样不是就省心省力了嘛。于是说干就干,自己写了一个 cli:vea-cli,大家也可以使用,只要执行以下命令就好,如下

npm install vea-cli -g
vea-cli init project-name

github 源码地址

下面是实现步骤

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/vea-cli (无文件扩展名)

// 告诉执行环境用node来执行
#!/usr/bin/env node

// 添加命令的库
const program = require('commander')

// 拿到package.json 里的版本号
const packageJson = require('../package.json')
const init = require('../lib/init')

//  执行  vea-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 配置项
 */
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/admin-template
// #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": "vea-cli",
  "version": "1.0.1",
  "description": "vue element-ui admin 项目初始化工具",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "bin": {
    "vea-cli": "./bin/vea-cli"
  },
  "keywords": [
    "vue",
    "vue-cli",
    "vea-cli",
    "vue element-ui 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 会把vea-cli命令链接到全局

npm unlink vea-cli 可以删除掉

执行就可以看到效果

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

./publish.sh 执行成功后的显示
在这里插入图片描述

6.发布完成后测试

npm i -g vea-cli

如果没有这个包的话看一下,npm 源是不是http://registry.npmjs.org,taobao源同步有时差

7.实现效果

在这里插入图片描述

8.发布后取消或删除 npm 包

强制取消,仅允许最近 72 小时内发布的版本取消发布

npm unpublish --force

删除已经发布好的包

npx force-unpublish package-name '原因描述'

参考链接

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

5.https://github.com/ianstormtaylor/download-github-repo

6.https://github.com/tj/commander.js

7.https://www.cnblogs.com/wangming1002/p/10973759.html

Logo

前往低代码交流专区

更多推荐