实现一个自己的脚手架
简介
本文章主要是记录一下,前端实现一个脚手架的过程。本文章创建的脚手架实现了模版创建以及从git拉取两个功能,自定义的功能暂未实现。
需要准备的依赖
1、inquirer : 是常规交互式命令行用户接口的集合,提供给 Node.js 一个方便嵌入,漂亮的命令行接口node ,会简化询问终端用户问题,解析,验证答案,提供错误反馈等等功能;
2、ora:一个终端loading动画;
3、shelljs:用于执行shell操作;
4、chalk:终端显示文字美化;
开始创建脚手架
一、首先初始化node项目
npm init -y 创建 package.json,并在package.json文件中添加,bin里边的key将是你的全局命令而value是你的命令的入口文件;
"bin": {"mycli": "index.js" },
二、创建脚手架
首先在入口文件的顶部写上如下代码,这句代码的意思是使用node解释器,对代码进行解释;
#!/usr/bin/env node
1、获取要创建的项目名称以及项目源(template模板、git)
// 问题列表
const projectTypeList = [
{
type: "input",
message: "请输入项目名称",
name: "name"
},
{
type: 'list',
message: '选择项目类型',
name: 'projectType',
choices: ['template', 'custom', 'git', 'updateTemplate'] // 通过fs模块读取tempate目录下的目录列表
}
]
// 获取输入答案
let { projectType, name } = await inquirer.prompt(projectTypeList);
// 获取执行命令的路径
let _path = process.cwd();
// 进入
shell.cd(_path)
// 判断是否在目录下已存在重名文件
await hasFile(name)
2、判断目录下是否存在同名文件
判断目录下是否存在同名文件,如果存在就询问是否删除,不删除结束进程;
async function hasFile(name) {
if (existsSync(name)) {
ora().warn(chalk.red(`目录下已存在${name}文件夹`))
var questions = [
{
type: 'confirm',
name: 'isRemoveDir',
message: `是否删除 ${name} ?`,
default: false,
}
]
try {
const { isRemoveDir } = await inquirer.prompt(questions)
if (isRemoveDir) {
shell.rm('-rf', name);
ora().succeed(chalk.green(chalk.green(`删除 ${name}成功`)))
} else {
ora().fail(chalk.red("项目构建失败"))
process.exit();
}
} catch (error) {
log(chalk.red('createProject错误:', error))
}
}
}
3、创建项目
使用fs模块读取本地存在模板并返回给用户,用户选择模版,使用shelljs 将用户选择的模版复制到当前文件夹下;
const templateList = [
{
type: 'list',
message: '请选择项目类型',
name: 'template',
choices: readdirSync(path.join(__dirname, 'template')) // 通过fs模块读取tempate目录下的目录列表
}
]
const { template } = await inquirer.prompt(templateList)
let np = path.join(__dirname, 'template', template);
shell.cp('-R', np + '/', name) // shell cp
ora().succeed(chalk.green(`拉取 '${template}' 项目成功!`))
shell.cd(name) // shell cd
4、安装依赖
询问用户是否需要自动安装依赖,此处使用exec另开一个进程执行依赖安装操作,如果在此进程进行会阻塞进程,loading动画将会停止;
const autoInstall = [
{
type: 'confirm',
name: 'isInstall',
message: `是否安装依赖(node_modules)?`,
default: false,
}
]
let { isInstall } = await inquirer.prompt(autoInstall)
if (isInstall) {
log('安装模块 --- npm install')
ora().info(`${chalk.yellow('安装耗时可能会很长,请耐心等待,您也可以通过 ctrl+c停止安装, 手动 npm install')}`)
const spinner = ora(`${chalk.blue('安装依赖中')}`)
spinner.start()
exec('npm install', { encoding: 'utf- 8' }, function (err, stdout, stderr) {
if (err) console.log(err)
}).on('exit', function (code) {
spinner.succeed('模块安装完成')
shell.exec("npm start");
spinner.succeed('项目启动成功')
process.exit()
});
} else {
process.exit()
}
5、项目启动
shell.exec("npm start");
三、总结
使用模板创建项目的流程大体就是这些,使用git仓库代码后续更新,后续要有一些优化代码并没有贴出,exec我是对其进行了一个封装封装成了promise方便使用,因为后边这个方法会经常使用。其次还有全局命令的原理会另写文章进行解释。
文章中如有问题欢迎大家批评指正🙏。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)