本文适用于通过命令行生成demo文件的需求,希望可以给到你一点思路。
背景
最近在开发的过程中沉淀组件
但是每写一个组件的话就要重新去复制粘贴很多重复的demo文件,最后再在里面开发。有点麻烦,就用node.js写了一个输入命令就能生成组件的demo。
应该不是最好的实现,不过记录一下仅供参考!
准备
首先搞个项目文件夹init一下生成package.json
npm install inquirer
写一个你想要复制生成的demo文件,变量的话可以用模版引擎的语法(eg:{{变量名}})
ps:该项目的模版引擎是我手动正则实现的,建议用现成的,性能会比较好
首先我们在package.json中写道
"scripts": {
....其他
"cli": "node ./cli.js"
},
然后定义我们的cli.js文件,这个文件的作用是
- 获取用户输入的变量名
- 校验变量名是否规范
- 递归demo文件夹
- 获取文件内容并根据模版引擎替换变量
- 写入新文件夹中
代码
#!/usr/bin/env node
var fs = require('fs');
const inquirer = require('inquirer');
var path = require("path");
// 用户输入组件名
const promptList = [{
type: 'input',
message: '请输入你的组件名',
name: 'name',
default: "demo" // 默认值
}];
// 获取组件名变量 校验写入
inquirer.prompt(promptList).then(answers => {
if (reg(answers.name)) {
write(answers)
} else {
console.log('当前组件名不合法,请确认是否为首字母大写的全英文字符');
}
})
// 组件名规则校验
function reg(name) {
return /^[A-Z][A-z]*/.test(name)
}
// 写入函数
function write(data) {
const {name} = data
// 看当前目录是否存在
fs.exists(`component/${data.name}`, function (exists) {
if (exists) {
console.log('该组件已存在');
return
}
// 创建目录
fs.mkdir(`component/${data.name}`, function (error) {
if (error) {
console.log(error);
return false;
}
console.log('创建目录成功');
// 递归文件夹复制
fileDisplay('component/Demo', name)
})
})
}
function fileDisplay(filePath, name){
// 外层文件夹内容复制
dirContentReplace(filePath, 'Demo', name)
//根据文件路径读取文件,返回文件列表
fs.readdir(filePath,function(err,files){
if(err){
console.warn(err)
}else{
//遍历读取到的文件列表
files.forEach(function(filename){
//获取当前文件的绝对路径
var filedir = path?.join(filePath,filename);
//根据文件路径获取文件信息,返回一个fs.Stats对象
fs.stat(filedir,function(eror,stats){
if(eror){
console.warn('获取文件stats失败');
}else{
// var isFile = stats.isFile();//是文件
var isDir = stats.isDirectory();//是文件夹
if(isDir){
fs.mkdirSync(filedir.replace('Demo',name));
// 复制文件夹内容
dirContentReplace(filedir, 'Demo', name)
fileDisplay(filedir);//递归,如果是文件夹,就继续遍历该文件夹下面的文件
}
}
})
});
}
});
}
function dirContentReplace(filePath, srcStr, replaceStr) {
const obj = {
name: replaceStr
}
//readdir方法读取文件名
fs.readdir(filePath, 'utf8', function (err, files) {
if (err) return console.log(err);
//根据后缀名筛选要操作的文件
var targetFiles = files
targetFiles.forEach(function (item, index) {
var itemPath = path.join(filePath, item);
//readFile方法读取文件内容
fs.readFile(itemPath, 'utf8', function (err, data) {
if (data && replaceStr) {
// 正则书写模版引擎
result = data.replace(RegExp(/({{)(.*)(}})/, "g"),function (matchStr,group1,group2) {
return obj[group2]
});
console.log(result,'result');
//writeFile改写文件内容
fs.writeFile(itemPath.replace('Demo',replaceStr), result, 'utf8', function (err) {
if (err) return console.log(err);
});
}
});
});
});
}
看看效果吧!!!