本篇文章主要给大家介绍如何开发一个自己的前端脚手架,用来快速的创建模板和项目。
1.初始化项目文件
mkdir template-create //创建文件夹
cd template-create //进入该目录
npm init -y //创建一个package.json
使用以上的命令对项目进行文件的创建
创建一个package.json
创建文件和文件结构
bin
index.js
index.js
#!/usr/bin/env node
//该文件可以用node去执行
console.log(123);
//可以用命令 node ./bin/index.js来运行
使用其他方式来进行文件的运行
(1)配置package.json
"bin":"/bin/index.js"
(2)使用npm link链接到全局,npm i -g表示将某个插件下载到全局,而npm link则是将我们本地开发的插件连接到本地的全局
{
"name": "template-create",
"version": "1.0.0",
"main": "index.js",
"bin": "/bin/index.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC",
"description": ""
}
(3)当我们link完了之后就可以直接使用该name进行文件的运行
template-create
当npm link之后 如果文件发生什么变化 会及时的更新
2.相关包的使用和介绍
commander:命令行的处理工具
npm i commander
(1)引入:
#!/usr/bin/env node
// 该文件可以用 node 去执行
const { program } = require('commander');
// 定义程序名称和用法
program.name('template-create').usage('<command> [option]')
.description('A CLI tool for managing templates');
// 定义 `--version` 选项
program.option('-v, --version', 'tell the template version')
.action(() => {
console.log('Template version: 1.0.0');
});
// 定义 `clone` 命令
program.command('clone <source> [destination]')
.description('Clone a repository into a newly created directory')
.action((source, destination) => {
console.log('Source:', source);
console.log('Destination:', destination);
});
// 解析命令行参数
program.parse(process.argv);
// 获取所有选项
const options = program.opts();
console.log(options);
chalk:命令行的样式的工具
npm i chalk@4.0.0
//由于最新的模块是基于ESM,此工程的引用使用的是CJS,所以下载4的版本
const chalk = require('chalk')
//---------------------chalk----------------------
console.log(chalk.red(123));
//可以用Chalk来控制命令行中命令的颜色
inquire:命令行的交互的工具
npm i inquirer@8.0.0
inquirer
.prompt([
{
type:'input',//选项的类型
name:'food',//选项的键名
message:'what do you want to eat?',//提示信息
default:'Hamburger'//默认值
},
{
type:'confirm',
name:'hot',
message:'Do you eat spicy food?',
default:false
},
])
.then((answer)=>{
console.log(answer)//答应输入
})
.catch((error)=>{
if(error.isTtyError){
console.log('input error');//提示错误
}
})
ora:终端loading美化工具
npm i ora@5.0.0
const spinner = ora('Loading...').start()//创建一个开始的实例
setTimeout(()=>{
spinner.text = 'Network loading...';//加载过程的提示
spinner.color='red';//加载样式改变
},2000)
setTimeout(()=>{
spinner.succeed('Success!');//成功
spinner.fail('Network error');
spinner.color='green';
},4000)
gitclone:下载模板的工具
figlet:终端生成艺术字体
figlet('Wang shi yi is a beauty!',function(err,data){
if(err){
console.log('Something went wrong...');
console.log(err);
return;
}
console.log(data)
});
fs:用来操作本地目录
gitClone(repository, destination, options, callback)
gitClone(repoURL, name, { checkout: 'main' }, function (err){
})
-
repository: Git 仓库的 URL,支持 HTTP(S) 和 SSH 协议。 -
destination: 克隆到的本地路径(目录)。 -
options: 选项对象,支持以下字段:
checkout: 指定要检出的分支(例如main或develop)。如果不指定,默认会克隆整个仓库。
-
callback: 克隆完成后的回调函数,接受一个错误对象作为参数。如果克隆成功,err为null,否则为错误对象。
开发步骤
1. 导入相关的库
const { program } = require('commander');//创建命令
const figlet = require("figlet");//艺术字体
const chalk = require("chalk");//命令行样式
const fs = require('fs-extra');//路径的输入
const path = require('path');//路径
const inquirer = require('inquirer');//捕获用户的输入
const gitClone = require('git-clone');//远程clone
const ora = require('ora');//等待
2.使用commander库来进行创建
// 首行提示
program
.name('template-create')
.usage('<command> [option]')//尖括号必填 方括号选填
.description(chalk.green('一个快速并便利的模板创建脚手架!'));
// 版本
program.version(`v${require('../package.json').version}`);
//对命令进行说明
//对包的版本和package.json中的文件进行绑定
3.创建clone的命令
//创建项目的命令
program.command('create <app-name>')
.description('Clone a repository into a newly created directory')
.action(async (name) => {
//1.拿到当前目录
const targetPath = path.join(process.cwd(),name);
//2.判断是否存在
if(fs.pathExistsSync(targetPath))
{
//3.用一个常量来接收输入的结果
const answer = await inquirer.prompt([
{
type:'confirm',
message:chalk.red('该目录下已存在相同文件名的文件是否进行覆盖?'),
default:false,
name:'overwrite'
}
])
//4.对常量中的overwrite的布尔值进行判断
if(answer.overwrite){
fs.remove(targetPath);
console.log(chalk.green('删除成功!'));
}
}
//5.新建一个项目
const result = await inquirer.prompt([
{
type:'list',
name:'type',
message:'请选择你要创建的模板:',
choices:[
{
name:'vue',
value:'vue'
},
{
name:'react',
value:'react'
}
]
},
{
type:'list',
name:'ts',
message:'是否使用TypeScript',
choices:[
{
name:'是',
value:true
},
{
name:'否',
value:false
}
]
}
])
console.log(result);
const key = result.type+(result.ts?'&ts':'');
console.log(key);
const repoURL = ProjectList[key];
const spinner = ora(chalk.yellow('正在下载模板,请稍候...')).start(); // 显示加载动画
gitClone(repoURL, name, { checkout: 'main' }, function (err) {
if (err) {
// 下载失败
spinner.fail(chalk.red('模板下载失败,请检查仓库地址是否正确!'));
console.error(chalk.red('错误信息:'), err.message);
} else {
// 下载成功
spinner.succeed(chalk.green('模板下载成功!'));
fs.remove(path.join(targetPath,'.git'));
console.log(chalk.green('项目已成功创建,请执行以下的操作:'));
console.log(chalk.green(`\n cd ${name}`));
console.log(chalk.green(`npm install`));
console.log(chalk.green(`npm run dev\n`));
}
});
});
(1).获取路径 并查看当前目录下是否存在相同名称的文件
//1.拿到当前目录
const targetPath = path.join(process.cwd(),name);
//2.判断是否存在
if(fs.pathExistsSync(targetPath))
{
//3.用一个常量来接收输入的结果
const answer = await inquirer.prompt([
{
type:'confirm',
message:chalk.red('该目录下已存在相同文件名的文件是否进行覆盖?'),
default:false,
name:'overwrite'
}
])
//4.对常量中的overwrite的布尔值进行判断
if(answer.overwrite){
fs.remove(targetPath);
console.log(chalk.green('删除成功!'));
}
}
(2).如果不存在的话就获取用户的输入使用inquirie库来进行交互和输入结果的捕获
//5.新建一个项目
const result = await inquirer.prompt([
{
type:'list',
name:'type',
message:'请选择你要创建的模板:',
choices:[
{
name:'vue',
value:'vue'
},
{
name:'react',
value:'react'
}
]
},
{
type:'list',
name:'ts',
message:'是否使用TypeScript',
choices:[
{
name:'是',
value:true
},
{
name:'否',
value:false
}
]
}
])
console.log(result);
const key = result.type+(result.ts?'&ts':'');
console.log(key);
(3).创建一个对象里面用来写清楚要clone的模板的键值对,键为用户的输入,值为clone的仓库地址
const ProjectList={
'vue':'git@github.com:kfc-vme50/vue-template.git',
'react':'git@github.com:kfc-vme50/vue-template.git',
'vue&ts':'git@github.com:kfc-vme50/vue-template-ts.git',
'react&ts':'git@github.com:kfc-vme50/vue-template-ts.git',
}
(4).使用getClone的方法进行远程的clone
const repoURL = ProjectList[key];
const spinner = ora(chalk.yellow('正在下载模板,请稍候...')).start(); // 显示加载动画
gitClone(repoURL, name, { checkout: 'main' }, function (err) {
if (err) {
// 下载失败
spinner.fail(chalk.red('模板下载失败,请检查仓库地址是否正确!'));
console.error(chalk.red('错误信息:'), err.message);
} else {
// 下载成功
spinner.succeed(chalk.green('模板下载成功!'));
fs.remove(path.join(targetPath,'.git'));
console.log(chalk.green('项目已成功创建,请执行以下的操作:'));
console.log(chalk.green(`\n cd ${name}`));
console.log(chalk.green(`npm install`));
console.log(chalk.green(`npm run dev\n`));
}
});
4.NPM发布
1.创建一个NPM的账号
2.npm login
3.npm publish
发布过程中如果出现403代表有重复的名称
只需要修改package.json里面的文件即可