开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15天,点击查看活动详情
前言
紧接上一篇搭建自己的脚手架(二)---启动阶段以后,我们的准备工作已经ok了,这篇开始我们要开始注册命令行命令
如果有些同学还没使用过commander和inquire库,可以参考我的这篇文章使用commander和inquire创建我们的专属秘书,熟练以后,在来看这篇文章,效果更佳
注册脚手架命令和选项
一个脚手架必写的命令和选项有哪些?
- init命令:主要是为了初始化项目
- 帮助信息选项:提供帮助信息,对用户进行友好提示
- debug选项:用户可以开启debug模式---,方便用户调试
接下来我们先写一下注册函数,并把他添加到core函数中
core/cli/lib/index.js
const { program } = require("commander");
function registerCommand(){}
async function core() {
try {
// 命令启动前的检查
await prepare();
registerCommand();
} catch (error) {
log.error(error);
}
}
书写帮助信息和选项
core/cli/lib/index.js
function registerCommand(){
program
.usage("<command> [option]") // 帮助信息首行内容
.version(pkg.version) // 定义版本号
.option('-d,--debug', 'whether to enable debug modal', false); // 添加选项
}
创建init项目命令
program
.command('init <projectName>')
.option('-f, --force', 'whether to force init project', false)
.action((projectName, options) => {
console.log("projectName:",projectName,'options:',options);
})
监听debug 选项
program.on('option:debug', () => {
if (params.debug) {
process.env.LOG_LEVEL = 'verbose';
} else {
process.env.LOG_LEVEL = 'info';
}
// 设置log等级
log.level = process.env.LOG_LEVEL;
log.verbose('debug');
})
未注册的命令进行兜底
program.on('command:*', (obj) => {
const commands = program.commands.map((cmd) => cmd.name());
log.info('未知的命令 ' + obj[0]);
if (commands.length > 0) {
log.info('支持的命令 ' + commands.join(','));
}
})
这时我们的命令基本就注册好了,接下来就是完善的工作了,比如init后要进行项目创建的工作,因为要创建的内容比较多,所以我们分出一个包来进行写业务
实现init初始化功能
lerna create @wson-koa2-cli/init commands
创建好以后,我们初始化一下
commands/init/lib/index.js
'use strict';
function init(projectName, options) {
console.log('init', projectName, options);
}
module.exports = init;
然后我们把core/cli/lib/index.js中的注册的init命令的action属性的回调函数换一下
program
.command('init <projectName>')
.option('-f, --force', 'whether to force init project', false)
.action(init)
判断当前目录是否存在
async function init(projectName, options) {
// 当前命令行所在的目录
const cwd = process.cwd();
// 需要创建的目录地址
const targetDir = path.join(cwd, projectName);
// 目录是否已经存在?
if (fs.existsSync(targetDir)) {
// 是否要强制创建
if (options.force) {
await fs.remove(targetDir)
} else {
// 询问用户是否确定要覆盖目录
}
}
}
询问是否覆盖
// 是否要强制创建
if (options.force) {
await fs.remove(targetDir)
} else {
// 询问用户是否确定要覆盖目录
inquirer.prompt([
{
name: 'isOverwrite',
type: 'confirm',
message: '当前目录已经存在,是否需要覆盖?'
}
]).then(async(answer) => {
if (answer.isOverwrite) {
// 移除已存在的目录
console.log(`\r\nRemoving...`);
await fs.remove(targetDir);
}
})
}
接下来我们创建一个目录,然后测试一下
good没有问题
如果不存在则创建项目名称
完整的init代码如下
'use strict';
const fs = require('fs-extra');
const path = require('path');
const inquirer = require('inquirer');
const Generator = require('./generator');
async function init(projectName, options) {
// 当前命令行所在的目录
const cwd = process.cwd();
// 需要创建的目录地址
const targetDir = path.join(cwd, projectName);
// 目录是否已经存在?
if (fs.existsSync(targetDir)) {
// 是否要强制创建
if (options.force) {
await fs.remove(targetDir)
} else {
// 询问用户是否确定要覆盖目录
inquirer.prompt([
{
name: 'isOverwrite',
type: 'confirm',
message: '当前目录已经存在,是否需要覆盖?'
}
]).then(async(answer) => {
if (answer.isOverwrite) {
// 移除已存在的目录
console.log(`\r\nRemoving...`);
await fs.remove(targetDir);
}
})
}
} else {
// 如果不存在的话创建目录
fs.mkdirSync(targetDir);
}
}