自定义vue脚手架
项目初始化
创建项目,通过npm init
初始化。添加一个bin/index.js
文件,在package.json
当中指定bin
字段,指向bin/index.js
文件
js
#!/usr/bin/env node
console.log("this is modify-cli");
执行命令npm link
,我这个库的名称为modify-cli
,在cmd当中执行modify-cli
命令,就会执行bin/index.js
文件
常用的库
commander
commander 命令行工具,自定义选项option与命令command
js
#!/usr/bin/env node
const {program} = require("commander");
program.name("modify-cli").usage("<command> [options]");
program
.option("-d, --debug", "output extra debugging")
.option("-s, --small", "small pizza size")
.option("-p, --pizza-type <type>", "flavour of pizza");
program
.command("clone <source> [destination]")
.description("clone a repository into a newly created directory")
.action((source, destination) => {
// action接收到的参数分别是source和destination
console.log("clone command called", source, destination);
});
program.parse(process.argv);
const options = program.opts();
console.log("options:", options);
chalk
chalk 命令行打印美化
IMPORT: Chalk 5 is ESM. If you want to use Chalk with TypeScript or a build tool, you will probably want to use Chalk 4 for now.(Chalk 5是ES Module。如果您想使用Chalk与TypeScript或构建工具,现在可能 want to use Chalk 4)
js
const chalk = require('chalk');
console.log(chalk.blue.bold.underline.bgWhite('Welcome Use Modify-Cli!'));
Inquirer.js
Inquirer.js 用户交互工具包
和chalk一样,最新的v9.0也是es module,所以还是用8.0的版本。
js
const inquirer = require('inquirer');
inquirer
.prompt([
{
type: 'input',
name: 'name',
message: 'What is your name?',
default: 'modify-cli'
},
{
type: 'confirm',
name: 'confirm',
message: 'Are you sure?',
default: false
}
])
.then((answers) => {
console.log('answers:', answers);
})
.catch((error) => {
if (error.isTtyError) {
// Prompt couldn't be rendered in the current environment
} else {
// Something else went wrong
}
});
ora
ora loading效果
js
const ora = require('ora');
const spinner = ora('Loading...').start();
setTimeout(() => {
spinner.text = 'Downloading...';
spinner.color = 'red';
}, 2000);
setTimeout(() => {
// spinner.succeed("Downloading done!");
spinner.fail('Loading failed!');
}, 4000);
git-clone
figlet
figlet 打印艺术字
js
const figlet = require('figlet');
figlet('Modify-Cli', function (err, data) {
if (err) {
}
console.log(data);
});
fs-extra
fs-extra 原生fs的替代品
脚手架代码
简单实现一个modify-cli create my-project
js
#!/usr/bin/env node
const {program} = require("commander");
const chalk = require("chalk");
const inquirer = require("inquirer");
const ora = require("ora");
const figlet = require("figlet");
const fs = require("fs-extra");
const path = require("path");
const gitClone = require("git-clone");
const {read} = require("fs");
const gieResponse = {
vue: "https://gitee.com/iamkun/dayjs.git",
react: "https://gitee.com/iamkun/dayjs.git",
"react-ts": "https://gitee.com/iamkun/dayjs.git",
"vue-ts": "https://gitee.com/iamkun/dayjs.git",
};
// 首行提示
program.name("modify-cli").usage("<command> [options]");
// 设置版本号
program.version(`v${require("../package.json").version}`);
// 监听 --help 执行
program.on("--help", () => {
console.log(
`\r\nRun ${chalk.cyan(
"modify-cli <command> --help"
)} for detailed usage of given command\r\n`
);
});
// 添加命令
program
.command("create <project-name>")
.description("create a new project")
.action(async (name) => {
// 判断是否存在
const targetPath = path.join(process.cwd(), name);
const isExist = fs.existsSync(targetPath);
if (isExist) {
const answers = await inquirer.prompt([
{
type: "confirm",
name: "overwrite",
message: "当前文件夹已存在,是否覆盖",
default: false,
},
]);
if (answers.overwrite) {
// 覆盖(先做删除)再做拉取
fs.removeSync(targetPath);
} else {
console.log(chalk.red.underline("请更换一个项目名称,再重新创建"));
return;
}
}
inquirer
.prompt([
{
type: "list",
name: "template",
message: "请选择技术框架",
default: "vue",
choices: ["vue", "react"],
},
{
type: "confirm",
name: "ts",
message: "是否使用 typescript",
default: true,
},
])
.then((answers) => {
// 通过选择的结果,拉取对应的模板
const {template, ts} = answers;
const key = ts ? `${template}-ts` : template;
const gitUrl = gieResponse[key];
const spinner = ora(`${name} Code Loading...`).start();
gitClone(gitUrl, name, {checkout: "master"}, (err) => {
if (err) {
console.log(chalk.red(err));
spinner.fail(`${name} 项目创建失败!`);
} else {
spinner.succeed(`${name} 项目创建成功!`);
// 把 .git 目录删除,把 .github 目录删除
fs.removeSync(path.join(targetPath, ".git"));
fs.removeSync(path.join(targetPath, ".github"));
console.log(chalk.green(`\r\n cd ${name}`));
console.log(chalk.green(" npm install"));
console.log(chalk.green(" npm run dev"));
figlet("Modify-Cli!", function (err, data) {
if (err) {
console.dir(err);
return;
}
console.log(data);
});
}
});
});
});
program.parse(process.argv);
项目发布
发布时先切换到官方源
bash
npm config set registry https://registry.npmjs.org
# npm config set registry https://registry.npm.taobao.org
# 在发布之前可以执行查看发布的结果
# npm pack
npm login
npm publish
使用脚手架
bash
npm i modify-cli -g
modify-cli create my-project