Skip to content

Commit

Permalink
feat(projects): can create routing information in a routing file & as…
Browse files Browse the repository at this point in the history
…sign layout manually & custom error boundary path
  • Loading branch information
mufeng889 committed Aug 24, 2024
1 parent 732bb7c commit 37b11ee
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 12 deletions.
74 changes: 63 additions & 11 deletions src/route-core/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { formatCode } from '../shared/prettier';
import { FIRST_LEVEL_ROUTE_COMPONENT_SPLIT, LAYOUT_PREFIX, VIEW_PREFIX } from '../constants';
import type { ElegantConstRoute, ElegantReactRouterOption, RouteConstExport } from '../types';
import { createPrefixCommentOfGenFile } from './comment';
import { log } from './log';

export async function genConstFile(tree: ElegantRouterTree[], options: ElegantReactRouterOption) {
const { cwd, constDir } = options;
Expand All @@ -17,6 +18,7 @@ export async function genConstFile(tree: ElegantRouterTree[], options: ElegantRe

const code = await getConstCode(tree, options);


await writeFile(routesFilePath, code, 'utf8');
}

Expand All @@ -31,19 +33,27 @@ async function getConstCode(trees: ElegantRouterTree[], options: ElegantReactRou
await writeFile(routeFilePath, code, 'utf-8');
}


const md = await loadFile<RouteConstExport>(routeFilePath, { parser: { parse } });


const autoRoutes = trees.map(item => transformRouteTreeToElegantConstRoute(item, options));

const oldRoutes = JSON.parse(JSON.stringify(md.exports.generatedRoutes)) as ElegantConstRoute[];

const updated = getUpdatedRouteConst(oldRoutes, autoRoutes, options);


const updated =await getUpdatedRouteConst(oldRoutes, autoRoutes, options);

md.exports.generatedRoutes = updated as any;


let { code } = generateCode(md);


code = transformComponent(code);


const formattedCode = await formatCode(code);

const removedEmptyLineCode = formattedCode.replace(/,\n\n/g, `,\n`);
Expand All @@ -65,27 +75,55 @@ export const generatedRoutes: GeneratedRoute[] = [];
return code;
}

function getUpdatedRouteConst(
async function getUpdatedRouteConst(
oldConst: ElegantConstRoute[],
newConst: ElegantConstRoute[],
options: ElegantReactRouterOption
) {
const oldRouteMap = getElegantConstRouteMap(oldConst);

const updated = newConst.map(item => {


const updated =await Promise.all(newConst.map(async (item)=> {
const oldRoute = oldRouteMap.get(item.name);
let config={} as ElegantConstRoute
if (options.routeInfoByFile) {
const configFile=item.name.split("_").join('/')+'/'+options.routeInfoFileName

const {cwd,pageDir}=options
const routeFilePath = path.posix.join(cwd, pageDir,configFile);

try {
const md = await loadFile<RouteConstExport>(routeFilePath, { parser: { parse } });
config = JSON.parse(JSON.stringify(md.exports)) as ElegantConstRoute;

} catch (error:any) {

log('Note that no file related to routing information is created in this file:'+' '+error.path, 'info', options.log);
}
}


if (!oldRoute) {
if (options.routeInfoByFile) {
Object.assign(item,config)
}
return item;
}


const { name, path: routePath, component, children, meta, ...rest } = item;


const updatedRoute = { ...oldRoute, path: routePath };

const isFirstLevel = !name.includes(PAGE_DEGREE_SPLITTER) && !children?.length;

if (oldRoute.component && component) {


if (config.layout||oldRoute.layout) {
updatedRoute.component = 'layout.'+ config.layout||oldRoute.layout;
}else if (oldRoute.component && component) {
if (isFirstLevel) {
const { layoutName: oldLayoutName } = resolveFirstLevelRouteComponent(oldRoute.component);
const { layoutName: newLayoutName } = resolveFirstLevelRouteComponent(component);
Expand All @@ -101,31 +139,41 @@ function getUpdatedRouteConst(
const layoutName = oldRoute.component.replace(LAYOUT_PREFIX, '');
const hasLayout = Boolean(options.layouts[layoutName]);

if (isView || (isLayout && !hasLayout)) {


if (isView || (isLayout && !hasLayout)) {
updatedRoute.component = component;
}

}
}


mergeObject(updatedRoute, rest);

if (!updatedRoute.meta && meta) {
updatedRoute.meta = meta;
}

if (updatedRoute.meta && meta) {
mergeObject(updatedRoute.meta, meta);
}
if (options.routeInfoByFile) {
Object.assign(updatedRoute,config)
}


if (children?.length) {
updatedRoute.children = getUpdatedRouteConst(oldRoute?.children || [], children, options);
updatedRoute.children =
await getUpdatedRouteConst(oldRoute?.children || [], children, options);
}

return updatedRoute;
});
}));

return updated;
}
}




function mergeObject<T extends Record<string, unknown>>(target: T, source: T) {
const keys = Object.keys(source) as (keyof T)[];
Expand All @@ -140,6 +188,7 @@ function mergeObject<T extends Record<string, unknown>>(target: T, source: T) {
function getElegantConstRouteMap(constRoutes: ElegantConstRoute[]) {
const routeMap = new Map<string, ElegantConstRoute>();


function recursiveGetElegantConstRoute(routes: ElegantConstRoute[]) {
routes.forEach(item => {
const { name, children } = item;
Expand All @@ -164,9 +213,12 @@ function getElegantConstRouteMap(constRoutes: ElegantConstRoute[]) {
* @param options the plugin options
*/
function transformRouteTreeToElegantConstRoute(tree: ElegantRouterTree, options: ElegantReactRouterOption) {


const { defaultLayout, onRouteMetaGen } = options;
const { routeName, routePath, children = [] } = tree;


const layoutComponent = `${LAYOUT_PREFIX}${defaultLayout}`;
const firstLevelRouteComponent = getFirstLevelRouteComponent(routeName, defaultLayout);

Expand Down Expand Up @@ -233,8 +285,8 @@ function resolveFirstLevelRouteComponent(component: string) {
}

function transformComponent(routeJson: string) {
const COMPONENT_REG = /"component":\s*"(.*?)"/g;

const COMPONENT_REG = /"component":\s*"(.*?)"/g;
const result = routeJson.replace(COMPONENT_REG, match => {
const [component, viewOrLayout] = match.split(':');

Expand Down
3 changes: 3 additions & 0 deletions src/route-core/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export function createPluginOptions(erOptions: ElegantRouterOption, options?: Pa
const DTS_DIR = 'src/types/elegant-router.d.ts';
const IMPORT_DIR = 'src/router/elegant/imports.ts';
const CONST_DIR = 'src/router/elegant/routes.ts';
const ROUTE_INFO_FILENAME = 'config.ts';
const TRANSFORM_DIR = 'src/router/elegant/transform.ts';
const CUSTOM_ROUTES_MAP: Record<string, string> = {
root: '/',
Expand All @@ -29,6 +30,8 @@ export function createPluginOptions(erOptions: ElegantRouterOption, options?: Pa
map: {},
names: []
},
routeInfoByFile: true,
routeInfoFileName:ROUTE_INFO_FILENAME,
layouts: DEFAULT_LAYOUTS,
defaultLayout: Object.keys(DEFAULT_LAYOUTS)[0],
layoutLazyImport: _name => true,
Expand Down
2 changes: 1 addition & 1 deletion src/route-core/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import type { FunctionComponent } from "react";
import type { ElegantConstRoute } from '@ohh-889/react-auto-route';
import type { RouteMap, RouteKey, RoutePath } from '@elegant-router/types';
import { redirect } from 'react-router-dom'
import ErrorBoundary from '../../../ErrorBoundary.tsx'
import ErrorBoundary from "${options.errorBoundaryPath||'../../../ErrorBoundary.tsx'}"
type CustomRouteObject = Omit<RouteObject, 'Component'|'index'> & {
Expand Down
3 changes: 3 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,9 @@ export interface ElegantReactRouterOption extends ElegantRouterOption {
* @param routeName the route name
*/
onRouteMetaGen(routeName: string): Record<string, unknown>;
errorBoundaryPath?: string
routeInfoByFile?: boolean,
routeInfoFileName?:string
}

export type CustomRouteConfig = {
Expand Down

0 comments on commit 37b11ee

Please sign in to comment.