first commit

This commit is contained in:
编码猿
2024-09-27 00:58:46 +08:00
commit 92916abf8f
156 changed files with 19331 additions and 0 deletions

View File

@@ -0,0 +1,283 @@
const Glob = require('glob');
const pify = require('pify');
const path = require('path');
const fs = require('fs');
const { parseComponent } = require('vue-template-compiler')
const glob = pify(Glob);
let globPath = "";
let OptionSetting = {};
// 获取文件路径,构造路由参数数组
generateRoutesAndFiles = async (PagePath) => {
const files = {};
(await glob(`${PagePath}/**/*.{vue,js,tsx,jsx}`, {
cwd: path.resolve(process.cwd(), OptionSetting.RootFolderName),
ignore: ['**/*.test.*', '**/*.spec.*', '**/-*.*']
})).forEach((f) => {
const key = f.replace(/\.(js|vue)$/, '')
if (/\.vue$/.test(f) || !files[key]) {
files[key] = f.replace(/('|")/g, '\\$1')
}
});
return createRoutes(
Object.values(files),
path.resolve(process.cwd(), OptionSetting.RootFolderName),
PagePath
)
};
// 填充路由配置
// `Utils.AsyncComponentHook('${camelCase(keys.join('-').replace('_', ''))}')`
const createRoutes = function createRoutes(files, srcDir, pagesDir) {
const routes = [];
files.forEach((file) => {
const keys = file
.replace(RegExp(`^${pagesDir}`), '')
.replace(/\.(vue|js)$/, '')
.replace(/\/{2,}/g, '/')
.split('/')
.slice(1);
const route = {
name: '',
path: '',
component: `_() => import(/* webpackChunkName: '${keys.toString().replace(/,/g, "")}' */ '@/${pagesDir}/${keys.join('/')}.vue')`,
meta: JSON.parse(routeMeta(file))
};
let parent = routes;
keys.forEach((key, i) => {
const sanitizedKey = key.startsWith('_') ? key.substr(1) : key;
route.name = route.name
? route.name + '-' + sanitizedKey
: sanitizedKey;
route.name += key === '_' ? 'all' : '';
const child = parent.find(parentRoute => parentRoute.name === route.name);
if (child) {
child.children = child.children || [];
parent = child.children;
route.path = '';
} else if (key === 'index' && i + 1 === keys.length) {
route.path += i > 0 ? '' : '/';
} else {
route.path += '/' + getRoutePathExtension(key);
if (key.startsWith('_') && key.length > 1) {
route.path += '?';
}
}
});
parent.push(route);
});
sortRoutes(routes);
return cleanChildrenRoutes(routes)
};
const startsWithAlias = aliasArray => str => aliasArray.some(c => str.startsWith(c));
const reqSep = /\//g;
const sysSep = escapeRegExp(path.sep);
const normalize = string => string.replace(reqSep, sysSep);
const startsWithSrcAlias = startsWithAlias(['@', '~']);
function routeMeta(f) {
let meta = {};
const VuePath = path.join(__dirname,`../../.${OptionSetting.RootFolderName}/${f}`);
let VueSource = fs.readFileSync(VuePath);
const parsed = parseComponent(VueSource.toString(), { pad: 'space' });
const routeMetaBlock = parsed.customBlocks.find(
b => b.type === 'route-meta'
);
if(routeMetaBlock) {
return routeMetaBlock.content;
} else {
return JSON.stringify({
test: `请在组件配置route-meta 标签参考文档https://www.npmjs.com/package/vue-cli-plugin-autorouter`
})
}
}
const r = function r(...args) {
const lastArg = args[args.length - 1];
if (startsWithSrcAlias(lastArg)) {
return wp(lastArg)
}
return wp(path.resolve(...args.map(normalize)))
};
function baseToString(value) {
if (typeof value == 'string') {
return value;
}
if (isArray_1(value)) {
return _arrayMap(value, baseToString) + '';
}
if (isSymbol_1(value)) {
return symbolToString ? symbolToString.call(value) : '';
}
var result = (value + '');
return (result == '0' && (1 / value) == -INFINITY) ? '-0' : result;
}
function toString(value) {
return value == null ? '' : baseToString(value);
}
function escapeRegExp(string) {
const reRegExpChar = /[\\^$.*+?()[\]{}|]/g,
reHasRegExpChar = RegExp(reRegExpChar.source);
string = toString(string);
return (string && reHasRegExpChar.test(string)) ?
string.replace(reRegExpChar, '\\$&') :
string;
}
const isWindows = /^win/.test(process.platform);
const wp = function wp(p = '') {
if (isWindows) {
return p.replace(/\\/g, '\\\\')
}
return p
};
const getRoutePathExtension = (key) => {
if (key === '_') {
return '*'
}
if (key.startsWith('_')) {
return `:${key.substr(1)}`
}
return key
};
const DYNAMIC_ROUTE_REGEX = /^\/(:|\*)/;
/**
* 排序路由
* @param {*} routes
*/
function sortRoutes(routes) {
routes.sort((a, b) => {
if (!a.path.length) {
return -1
}
if (!b.path.length) {
return 1
}
if (a.path === '/') {
return DYNAMIC_ROUTE_REGEX.test(b.path) ? -1 : 1
}
if (b.path === '/') {
return DYNAMIC_ROUTE_REGEX.test(a.path) ? 1 : -1
}
let i
let res = 0
let y = 0
let z = 0
const _a = a.path.split('/')
const _b = b.path.split('/')
for (i = 0; i < _a.length; i++) {
if (res !== 0) {
break
}
y = _a[i] === '*' ? 2 : _a[i].includes(':') ? 1 : 0
z = _b[i] === '*' ? 2 : _b[i].includes(':') ? 1 : 0
res = y - z
// If a.length >= b.length
if (i === _b.length - 1 && res === 0) {
// unless * found sort by level, then alphabetically
res = _a[i] === '*' ? -1 : (
_a.length === _b.length ? a.path.localeCompare(b.path) : (_a.length - _b.length)
)
}
}
if (res === 0) {
res = _a[i - 1] === '*' && _b[i] ? 1 : (
_a.length === _b.length ? a.path.localeCompare(b.path) : (_a.length - _b.length)
)
}
return res
})
routes.forEach((route) => {
if (route.children) {
sortRoutes(route.children)
}
})
return routes
}
function cleanChildrenRoutes(routes, isChild = false) {
let start = -1
const routesIndex = []
routes.forEach((route) => {
if (/-index$/.test(route.name) || route.name === 'index') {
const res = route.name.split('-')
const s = res.indexOf('index')
start = start === -1 || s < start ? s : start
routesIndex.push(res)
}
})
routes.forEach((route) => {
route.path = isChild ? route.path.replace('/', '') : route.path
if (route.path.includes('?')) {
const names = route.name.split('-')
const paths = route.path.split('/')
if (!isChild) {
paths.shift()
}
routesIndex.forEach((r) => {
const i = r.indexOf('index') - start
if (i < paths.length) {
for (let a = 0; a <= i; a++) {
if (a === i) {
paths[a] = paths[a].replace('?', '')
}
if (a < i && names[a] !== r[a]) {
break
}
}
}
})
route.path = (isChild ? '' : '/') + paths.join('/')
}
route.name = route.name.replace(/-index$/, '')
if (route.children) {
if (route.children.find(child => child.path === '')) {
delete route.name
}
route.children = cleanChildrenRoutes(route.children, true)
}
})
return routes
}
function camelCase(string) {
return string.replace(/-([a-z])/g, function (all, letter) {
return letter.toUpperCase();
});
}
module.exports.creatRouter = (flag = false, root) => {
if (flag) return;
OptionSetting = root;
generateRoutesAndFiles(OptionSetting.TemplateFolderName).then(res => {
let string = `// 根据page目录结构自动生成的路由配置文件\n// 参考Nuxt.jshttps://zh.nuxtjs.org/guide/routing\n// @ts-ignore\n\n`;
string += `export const AutoRoutesConfig = ${JSON.stringify(res, null, 2)};`
.replace(/"component": "(\w+?)"/g, `"component": $1`)
.replace(/"(\w+?)":/g, '$1:')
.replace(/"_()/g, "")
.replace(/vue'\)"/g, "vue')");
let buildPath = path.resolve(process.cwd(), path.join(__dirname, OptionSetting.SaveConfigPath));
fs.writeFileSync(buildPath, string);
})
};