解决方向
公司技术栈从Vue转型到React之后,后台管理页面项目的目光也从vue系列UI库的Pro Admin方向聚焦到Umi及Ant Pro相关
本着能少写代码就少写的理念,开始打起了生成代码的念头,毕竟能多点摸鱼的时间是一点多给自己提升能力的机会是好的
受Umi Ui可视化编程辅助工具的影响,我们这种大量C+V的功能也可以写一个类似一键生成代码的脚本
因为是自用,主要是记录一下这种思路
,所以没有太多繁琐的逻辑和边界判断,整个过程很快啊,pa的一下就好了~
该文章只适合大量逻辑相同的展示页面,大量逻辑不相同的页面本身也不适合生成对不对 <_<
目录结构
|-- result
|-- template
|--index.js
|-- index.js
// * result 用来放置生成结果的文件夹
// * template 用来放置需要生成的模板文件
// * template/index.js 用来举例用的文件
// * index 入口文件
我们可以用Node的什么?
主要用node的fs模块,我们需要用到的api:
- access 测试用户对 path 指定的文件或目录的权限
- readdir 读取目录的内容
- mkdir 异步地创建目录
- readFile 异步地读取文件的全部内容
- writeFile 异步地将数据写入到一个文件,如果文件已存在则覆盖该文件
writeFile 中的data 可以是字符串或 buffer 这个地方是重点
支棱起来
准备工作做得差不多了,把这几个api拼接起来就是我们想要的了
- 先用
access
函数检查一下我们的输出/输入目录是否存在,否则给它建一个
// * index.js
const start = ({ sourceURL, targetURL, sourceData }) =>
fs.access(targetURL, (err) => {
if (err) { // *不存在进行mkdir
fs.mkdir(targetURL, () => {
copy({ sourceURL, targetURL, sourceData });
});
} else { // *已存在进行copy
copy({ sourceURL, targetURL, sourceData });
}
});
- 接着完善
copy
函数
// * index.js
const copy = ({ sourceURL, targetURL, sourceData }) =>
fs.readdir(sourceURL, (err, paths) => { // *读取目录
if (err) {
if (err.code === 'ENOENT') {
console.error('源路径不存在');
return;
}
throw err;
};
paths.forEach(path => { // *遍历readdir反馈的结果
const _source = `${sourceURL}/${path}`, // *本次输入地址
_target = `${targetURL}/${path}`; // *本次输出地址
fs.stat(_source, (err, st) => { // *读取文件状态,我们要区分本次操作的是目录还是文件
if (err) {
console.error(`目标: ${_source} 状态:读取状态失败`);
return;
}
if (st.isFile()) { // *判断是否为文件
fs.readFile(_source, 'utf8', (err, data) => { // *读取文件的数据
if (err) {
console.error(`目标: ${_source} 状态:读取失败`);
return;
}
// *替换开始---
// *code...
// *替换结束---
// !为新地址生成文件
fs.writeFile(_target, data, 'utf8', (err) => {
if (err) {
console.error(`目标: ${_target} 状态:写入失败`);
console.log(`\u001b[42m biu \u001b[0m目标: \u001b[34m${_target}\u001b[0m 状态: \u001b[31m写入失败\u001b[0m`)
return;
}
console.log(`\u001b[42m biu \u001b[0m目标: \u001b[34m${_target}\u001b[0m 状态: \u001b[32m写入成功\u001b[0m`)
});
});
} else if (st.isDirectory()) { // *如果是目录则递归调用自身
start({
sourceURL: _source,
targetURL: _target,
sourceData,
})
}
});
});
});
搞到这里一个基本的文件查找/读取/写入已经完成了,最重要的一步“如何把模板文件替换成我们需要的文件”
正则替换文件内容(摸鱼核心)
我们在readFile
函数中可以得到正常的文件信息,然后可以用replace
去替换指定内容,完成大量相同逻辑页面的一键生成
// * index.js
// *定义我们要替换的数据
const sourceData = {
btnTitle: '天猫商品TOP10',
};
// !中间省略部分重复代码...
// *替换开始---
const { btnTitle } = sourceData;
data = data.replace(/__btnTitle__/, JSON.stringify(btnTitle));
// *替换结束---
// * template/index.js
// * 大量代码省略
<Button>__btnTitle__</Button>
// * 大量代码省略
__btnTitle__
是在文件中需要用来替换数据的占位符,可以根据自己喜好,随便写,只要可以和index.js中的replace
对上号即可
完事运行node index.js
,查看result文件夹的内容,直接✈✈✈
这时候就有会人说,你这还是要配置sourceDate才可以,和C+V没啥区别啊,不慌,这时候可以给后台大佬商量下,让他直接给你对应页面的sourceDate,让他按照这个格式给你,省了写swagger的时间了,什么?你说swagger都是自动化生成的,那也不慌,“矿刷新了,用钟师傅带他挖矿”?,总知,要么后台老哥人好我们啥都不用写直接node一下就好,不然自己就动手搞一下sourceData也好
脚本扩展
上面例子写了一个很简单的替换功能,开发中预设好字段
就可以一键替换【api接口/table的Columns配置/文案】等等,或者直接给sourceURL/targetURL路径改为实际项目页面存放的页面都是可以的,至于脚本生成出来的文件格式不好看,这个好说,不是有eslint嘛
关键是看自己工作中遇到啥,能搞就搞,不能搞还是要老老实实的写嘛
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!