Write your own cli and publish it to npm
Introduction: Everyone must have used vue-cli or create-react-app. You can generate a complete project with a simple command line, which is very easy to use. Since my company accepts a lot of projects, every time I create a new project, I copy the previous project code, which is troublesome, and I have to delete a lot of useless code, which is tiring. So I thought of imitating vue-cli to write a simple cli to create a project, so it saves worry and effort. So just do it and write a cli:, vea-cli
you can also use it, just execute the following command, as follows
npm install vea-cli -g
vea-cli init project-name
Here are the implementation steps
1. Project dependencies: (install first, steps omitted)
"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. Project directory structure
3. Core code
/bin/vea-cli (no file extension)
// 告诉执行环境用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
The focus is on the configuration of the bin field
{
"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. Local test
The implementation of the project root directory npm link
will vea-cli
command links to the global
npm unlink vea-cli
Can be deleted
You can see the effect after execution
vea-cli init project-name
5. Publish to npm (register your own account)
Create a new publish.sh in the project root directory
#!/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
Display after successful execution
6. Test after release
npm i -g vea-cli
If you don’t have this package, then take a look, is the npm source http://registry.npmjs.org? There is a time difference in taobao source synchronization
7. Realize the effect
8. Cancel or delete the npm package after publishing
Mandatory cancellation, only allowing the version released within the last 72 hours to be cancelled
npm unpublish --force
Delete the released package
npx force-unpublish package-name '原因描述'
Reference link
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