最近做管理后台,功能基本相似,于是写了个简单的代码生成器,当然只是用我们的项目,不具有通用性,但是确实一次不错的体验!
let fs = require('fs');
let pug = require('pug');
let pathNode = require('path');
// let dbIndex = require('./dataBase/index')
let basePath = pathNode.resolve(__dirname, '..', 'page');
// 文件路径
let cptName = process.argv.splice(2);
// 数据库名
let dbName = cptName[2] || 'changantp_sys';
// 数据库表名
let dbTableName = cptName[1];
let path = cptName[0].split('/');
let name = path[path.length - 1];
let dir = path[path.length - 2];
let initdir = path[path.length - 3];
let template = ['./template/template.pug', './template/template.vue'];
let inputFile = [`${basePath}/${initdir}/${dir}/${name}/${name}.vue`, `${basePath}/${initdir}/${dir}/${name}/fields.js`];
let db = require('./dataBase/db.js');
function transformStr (str) {
var re = /_(w)/g;
return str.replace(re, function ($0, $1) {
return $1.toUpperCase();
});
};
let data;
class BaseFunc {
// 检测目标文件夹是否存在
exists () {
return new Promise(async (resolve, reject) => {
for (let index of path) {
fs.existsSync(`${basePath}/${index}`) ? basePath = `${basePath}/${index}` : basePath = await this.mkdir(index);
}
resolve(basePath);
});
}
// 创建目标文件夹
mkdir (index) {
return new Promise((resolve, reject) => {
fs.mkdir(`${basePath}/${index}`, (err) => {
if (err) reject(err);
basePath = `${basePath}/${index}`;
resolve(basePath);
});
});
}
// 读取模板文件
readTemplate () {
return new Promise((resolve, reject) => {
let readPug, readVue;
for (let index of template) {
// 如果是pug文件
if (index.indexOf('.pug') > 0) {
readPug = () => {
return new Promise((resolve, reject) => {
db.sequelize.query(`select COLUMN_NAME, column_comment from information_schema.columns where table_name = "${dbTableName}" and TABLE_SCHEMA = "${dbName}"`).then((res) => {
let columnArr = [];
for (let index of res[0]) {
let column = Object.values(index);
columnArr.push(column);
}
for (let index of columnArr) {
index[0] = transformStr(index[0]);
}
data = {dataArr: columnArr};
let fn = pug.compileFile(index, {pretty: true});
resolve(fn(data).replace('="v-else"', '').replace('="long"', '').replace('="divided"', '').replace('="show-total"', '').replace('="show-elevator"', '').replace('="show-sizer"', '').replace(/="clearable"/g, '').replace('="inline"', ''));
});
});
};
} else if (index.indexOf('.vue') > 0) {
readVue = () => {
return new Promise((resolve, reject) => {
let readVueResult = fs.readFileSync(index);
resolve(readVueResult);
});
};
}
}
Promise.all([readPug(), readVue()]).then((res) => {
resolve(res[0] + '
' + res[1]);
});
});
}
// 写入目标文件
writeTargetFile (args) {
return new Promise((resolve, reject) => {
for (let index of inputFile) {
if (index.indexOf('.vue') > 1) {
fs.writeFileSync(index, args);
} else if (index.indexOf('.js') > 1) {
const tmpl = addInfos => `export const fields = {
${addInfos.map(addInfo =>
`'${addInfo[0]}': {
title: '${addInfo[1]}',
key: '${addInfo[0]}',
sortable: 'custom',
ellipsis: true,
120
}`
)}
};`;
fs.writeFileSync(index, tmpl(data.dataArr));
}
}
});
}
}
async function create () {
try {
let fn = new BaseFunc();
await fn.exists();
let response = await fn.readTemplate();
await fn.writeTargetFile(response);
process.exit(1);
} catch (error) {
console.error(error);
}
}
create();
模板采用的是pug,基本思路就是读取模板文件,然后根据数据库的字段和注释,自动生成table的表头信息,因为我们的后台全是表格
template div() Form(inline :model='queryForm' :label-width="90" class="formQueryStyle" v-show="isTableView") each tag, index in dataArr if index > 3 FormItem(v-show="isShowMore" label=`${tag[1]}`) Input(clearable placeholder="请输入" v-model=`queryForm.${tag[0]}Equals`) else FormItem(label=`${tag[1]}`) Input(clearable placeholder="请输入" v-model=`queryForm.${tag[0]}Equals`)
这是主要的模板文件部分,渲染的后为vue文件,其实代码很简单,具体我都不细说了,具体流程就是 node index 目标目录/目标子目录/目标文件 表名 数据库名