@uiw-admin/plugins
Version:
191 lines (190 loc) • 6.45 kB
JavaScript
/*
* @Description: 简单版本的 自动加载 model
*/
import fs from 'fs';
import path from 'path';
import createTemp from './temp';
import chokidar from 'chokidar';
import { getJSONData, stringToJson, getRouteMapModels, babelPluginComponents } from './../utils';
class RoutesWebpackPlugin {
constructor(props) {
// json 文件地址
this.jsonFilePath = '';
// js文件地址
this.jsFilePath = '';
// ts 文件地址
this.tsFilePath = '';
// 渲染路由数组
this.routes = [];
// 上一次的路由数据
this.preString = '';
// 下一次渲染路由数据
this.nextString = '';
// 根目录
this.cwd = '';
// 需要监听的文件目录
this.cwdConfig = '';
this.uiw = '';
// src/.uiw/modelsMap.json 地址
this.modelsMapJson = '';
// models 获取 src/.uiw/modelsMap.json 数据
this.modelsMapData = [];
this.lazyLoad = false;
this.jsonCode = '';
this.isTS = true;
// 生成临时路由
this.createTemps = (strs, isType) => {
if (['[]', 'export default []'].includes(strs)) {
this.preString = '';
this.nextString = '';
} else {
this.preString = this.nextString;
this.nextString = '';
}
if (!fs.existsSync(this.uiw)) {
fs.mkdirSync(this.uiw);
}
var content = ['js', 'ts'].includes(isType) ? this.jsonCode : strs;
var babelIcons = babelPluginComponents(content);
var routeTemp = createTemp(babelIcons.code, babelIcons.iconsList, isType);
fs.writeFileSync(path.resolve(process.cwd(), this.isTS ? 'src/.uiw/routes.tsx' : 'src/.uiw/routes.js'), routeTemp, {
encoding: 'utf-8',
flag: 'w+'
});
this.createRouteMapModels();
};
// 判断上一次和下一次
this.checkPreAndNext = isType => {
if (this.preString !== this.nextString) {
// 读取文件数据
var routerTemp = JSON.stringify(this.routes, null, 2);
// .replace(/\"component\": (\"(.+?)\")/g, (global, m1, m2) => {
// return `"component": ${m2.replace(/\^/g, '"')}`;
// })
// .replace(/\\r\\n/g, '\r\n')
// .replace(/\\n/g, '\r\n');
this.createTemps(routerTemp, isType);
}
};
// 获取文件内容
this.getFileContent = isType => {
var temps = '[]';
if (isType === 'json') {
this.nextString = fs.readFileSync(this.jsonFilePath, {
encoding: 'utf-8'
}).toString().trim();
if (this.nextString !== '') {
this.routes = stringToJson(this.nextString);
this.nextString = JSON.stringify(this.routes);
this.checkPreAndNext(isType);
return;
}
} else if (['js', 'ts'].includes(isType)) {
temps = 'export default []';
var filePath = '';
if (isType === 'js') {
filePath = this.jsFilePath;
} else {
filePath = this.tsFilePath;
}
var content = fs.readFileSync(filePath, {
encoding: 'utf-8'
});
var {
isJSON,
jsonArr,
jsonCode
} = getJSONData(content);
if (isJSON) {
this.routes = jsonArr;
this.jsonCode = jsonCode || 'export default []';
// this.nextString = JSON.stringify(jsonArr);
this.nextString = this.jsonCode;
this.checkPreAndNext(isType);
return;
}
}
this.createTemps(temps, isType);
};
// 判断文件优先级
this.JudgeFileType = () => {
var isType = 'json';
if (fs.existsSync(this.jsonFilePath)) {
isType = 'json';
} else if (fs.existsSync(this.tsFilePath)) {
isType = 'ts';
} else if (fs.existsSync(this.jsFilePath)) {
isType = 'js';
} else {
isType = false;
}
this.getFileContent(isType);
};
// 必须要存在这个文件 优先级 json > ts > js
this.jsonFilePath = path.resolve(process.cwd(), 'config/routes.json');
this.modelsMapJson = path.resolve(process.cwd(), 'src/.uiw/modelsMap.json');
this.jsFilePath = path.resolve(process.cwd(), 'config/routes.js');
this.tsFilePath = path.resolve(process.cwd(), 'config/routes.ts');
this.uiw = path.resolve(process.cwd(), 'src/.uiw');
this.isTS = fs.existsSync(path.join(process.cwd(), 'tsconfig.json'));
this.lazyLoad = !!(props != null && props.lazyLoad);
// ----
this.cwdConfig = path.resolve(process.cwd(), 'config');
this.cwd = path.resolve(process.cwd());
}
readModelsMapJSON() {
if (!this.lazyLoad) {
return;
}
if (fs.existsSync(this.modelsMapJson)) {
var modelsStr = fs.readFileSync(this.modelsMapJson, {
encoding: 'utf-8'
}).toString().trim();
if (modelsStr !== '') {
this.modelsMapData = stringToJson(modelsStr);
} else {
this.modelsMapData = [];
}
}
}
createRouteMapModels() {
if (!this.lazyLoad) {
fs.writeFileSync(path.resolve(process.cwd(), 'src/.uiw/routeMapModels.json'), "{}", {
encoding: 'utf-8',
flag: 'w+'
});
return;
}
var routeModels = getRouteMapModels(this.routes, this.modelsMapData);
var routeModelsStr = JSON.stringify(routeModels, (_, value) => value, 2).replace(/\\r\\n/g, '\r\n').replace(/\\n/g, '\r\n');
if (!fs.existsSync(this.uiw)) {
fs.mkdirSync(this.uiw);
}
fs.writeFileSync(path.resolve(process.cwd(), 'src/.uiw/routeMapModels.json'), "" + routeModelsStr, {
encoding: 'utf-8',
flag: 'w+'
});
}
apply(compiler) {
compiler.hooks.afterPlugins.tap('RoutesWebpackPlugin', () => {
this.readModelsMapJSON();
this.JudgeFileType();
if (process.env.NODE_ENV === 'development') {
chokidar.watch([this.cwdConfig, this.modelsMapJson], {
cwd: this.cwd
}).on('all', (event, path) => {
if (['change', 'add', 'unlink'].includes(event) && /src\/\.uiw\/modelsMap.json/.test(path)) {
this.readModelsMapJSON();
this.createRouteMapModels();
}
if (['change', 'add', 'unlink'].includes(event) && /config(\\|\/)routes.(js|json|ts)/.test(path)
// && ["config/routes.json", "config/routes.ts", "config/routes.js"].includes(path)
) {
this.JudgeFileType();
}
});
}
});
}
}
export default RoutesWebpackPlugin;