@vitjs/core
Version:
@vitjs/core
145 lines (144 loc) • 5.57 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = require("path");
const utils_1 = require("@vitjs/utils");
const cloneDeep_1 = __importDefault(require("lodash/cloneDeep"));
const uniq_1 = __importDefault(require("lodash/uniq"));
class Route {
constructor(options) {
this.routes = [];
this.service = options.service;
this.routes = options.routes;
this.dynamicImport = options.dynamicImport;
}
/**
* 解析路由组件配置,得到组件绝对路径和组件别名的映射
*/
resolveRoutes() {
const result = {};
let componentCursor = 0;
let wrapperCursor = 0;
const resolveRoute = (route) => {
if (route.component && !result[route.component]) {
route.component = (0, utils_1.winPath)((0, path_1.resolve)(this.service.paths.absSrcPath, route.component));
result[route.component] = `Component${componentCursor}`;
componentCursor += 1;
}
if (route.wrappers) {
route.wrappers.forEach((item) => {
const wrapper = (0, utils_1.winPath)((0, path_1.resolve)(this.service.paths.absSrcPath, item));
if (!result[wrapper]) {
result[wrapper] = `Wrapper${wrapperCursor}`;
wrapperCursor += 1;
}
});
}
if (route.routes) {
// eslint-disable-next-line @typescript-eslint/no-use-before-define
loopRoutes(route.routes);
}
};
const loopRoutes = (routes) => {
routes.forEach(resolveRoute);
};
loopRoutes(this.routes);
return result;
}
/**
* 输出路由配置,可做额外修改
*
* @param options
* @returns
*/
dumpRoutes(options) {
const { extraReplace, postDump } = options || {};
const clonedRoutes = (0, cloneDeep_1.default)(this.routes);
let modules = {};
if (!this.dynamicImport) {
modules = this.resolveRoutes();
}
const replaceComponent = (route) => {
if (route.component) {
route.component = (0, utils_1.winPath)((0, path_1.resolve)(this.service.paths.absSrcPath, route.component));
if (this.dynamicImport) {
let loading = '';
if (this.dynamicImport.loading) {
loading = `, loading: LoadingComponent`;
}
route.component = `dynamic({ loader: () => import('${route.component}')${loading}})`;
}
else {
route.component = modules[route.component];
}
}
};
const replaceWrappers = (route) => {
if (route.wrappers) {
route.wrappers = route.wrappers.map((item) => {
const wrapper = (0, utils_1.winPath)((0, path_1.resolve)(this.service.paths.absSrcPath, item));
if (this.dynamicImport) {
let loading = '';
if (this.dynamicImport.loading) {
loading = `, loading: LoadingComponent`;
}
return `dynamic({ loader: () => import('${wrapper}')${loading}})`;
}
else {
return modules[wrapper];
}
});
}
};
function loopRoute(route) {
replaceComponent(route);
replaceWrappers(route);
extraReplace === null || extraReplace === void 0 ? void 0 : extraReplace(route);
if (route.routes) {
loopRoutes(route.routes);
}
else {
// ref: https://stackoverflow.com/questions/49162311/react-difference-between-route-exact-path-and-route-path
// 没有子路由时赋值 exact
route.exact = true;
}
}
function loopRoutes(routes) {
routes.forEach(loopRoute);
}
loopRoutes(clonedRoutes);
const result = JSON.stringify(clonedRoutes, null, 2)
.replace(/\"component\": (\"(.+?)\")/g, (global, m1, m2) => {
return `"component": ${m2.replace(/\^/g, '"')}`;
})
.replace(/\"wrappers\": (\"(.+?)\")/g, (global, m1, m2) => {
return `"wrappers": ${m2.replace(/\^/g, '"')}`;
})
.replace(/\\r\\n/g, '\r\n')
.replace(/\\n/g, '\r\n');
return (postDump === null || postDump === void 0 ? void 0 : postDump(result)) || result;
}
patchRoutes(setRoutes) {
if (typeof setRoutes === 'function') {
this.routes = setRoutes(this.routes);
}
else {
this.routes = setRoutes;
}
}
getPaths({ routes }) {
return (0, uniq_1.default)(routes.reduce((memo, route) => {
let result = [...memo];
if (route.path) {
result.push(route.path);
}
if (route.routes) {
result = result.concat(this.getPaths({ routes: route.routes }));
}
return result;
}, []));
}
}
exports.default = Route;