From 8708eddd2d0eba4d5aee54420bbb4ee4f12dbd15 Mon Sep 17 00:00:00 2001 From: Tay Zheng Yu <32449414+ZhengYuTay@users.noreply.github.com> Date: Tue, 28 Jul 2020 17:02:06 +0800 Subject: [PATCH] Revert "refractor: move matchRoute to core (#47)" (#48) This reverts commit 28f5603752b78df26fbfaff5ff68feb414819be8. --- packages/core/src/index.ts | 2 +- packages/core/src/route/index.ts | 1 - packages/core/src/route/matchRoutes.ts | 19 ------------------- packages/core/src/route/route.ts | 7 +++---- packages/core/src/types/route.ts | 12 ++++++------ packages/router-react/src/types.ts | 14 +++++++++++--- packages/router/src/types.ts | 8 ++++---- packages/runtime-react/src/lib/index.ts | 7 ++++--- .../src/shuvi-app/router/matchRoutes.ts | 12 ++++++++++++ .../src/shuvi-app/router/renderRoutes.tsx | 1 - .../src/shuvi-app/view/ReactView.client.tsx | 6 +++--- .../src/shuvi-app/view/ReactView.server.tsx | 12 ++++++------ packages/shuvi/src/api/api.ts | 1 - packages/shuvi/src/api/types.ts | 2 +- packages/shuvi/src/lib/routes.ts | 10 ++++------ packages/types/src/runtime.d.ts | 18 ++++++++++++------ 16 files changed, 67 insertions(+), 65 deletions(-) delete mode 100644 packages/core/src/route/matchRoutes.ts create mode 100644 packages/runtime-react/src/shuvi-app/router/matchRoutes.ts diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 9e0385cc1..8e2c49682 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -11,6 +11,6 @@ export { default as React } from 'react'; export { App, IFile, File } from './app'; -export { Route, matchRoutes } from './route'; +export { Route } from './route'; export * from './types'; diff --git a/packages/core/src/route/index.ts b/packages/core/src/route/index.ts index 15647303b..e8168fd83 100644 --- a/packages/core/src/route/index.ts +++ b/packages/core/src/route/index.ts @@ -1,2 +1 @@ export { Route } from './route'; -export { matchRoutes } from './matchRoutes'; diff --git a/packages/core/src/route/matchRoutes.ts b/packages/core/src/route/matchRoutes.ts deleted file mode 100644 index 737d39c82..000000000 --- a/packages/core/src/route/matchRoutes.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { - matchRoutes as matcher, - PartialLocation, - IRouteObject, - IRouteMatch -} from '@shuvi/router'; - -export function matchRoutes< - Element = any, - RouteObject extends IRouteObject = IRouteObject ->( - routes: RouteObject[], - location: string | PartialLocation, - basename = '' -): IRouteMatch[] { - return ( - (matcher(routes, location, basename) as IRouteMatch[]) || [] - ); -} diff --git a/packages/core/src/route/route.ts b/packages/core/src/route/route.ts index ce94c7a8d..6d1b9a389 100644 --- a/packages/core/src/route/route.ts +++ b/packages/core/src/route/route.ts @@ -1,4 +1,3 @@ -// TODO import { join, relative, posix } from 'path'; import invariant from '@shuvi/utils/lib/invariant'; import { watch } from '@shuvi/utils/lib/fileWatcher'; @@ -67,7 +66,7 @@ function getRouteWeight(route: InternalRouteConfig): number { const weights: [string, string] = ['0', '0']; if (meta.isStaticRoute) { weights[0] = '1'; - } else if (route.caseSensitive) { + } else if (route.exact) { weights[1] = '1'; } @@ -151,7 +150,7 @@ export class Route { } else if (isLayout(file)) { const layoutRoute: InternalRouteConfig = { path: normalizeRoutePath(file.replace(/\/_layout$/, '/')), - caseSensitive: false, + exact: false, component: join(this._pagesDir, rawfile), __meta: { isStaticRoute: isStaicRouter(file) @@ -171,7 +170,7 @@ export class Route { } else { route = { path: routePath, - caseSensitive: !isLayout(file), + exact: !isLayout(file), component: join(this._pagesDir, rawFile), __meta: { isStaticRoute: isStaicRouter(file) diff --git a/packages/core/src/types/route.ts b/packages/core/src/types/route.ts index 6f6df9fd4..0fd30a9f6 100644 --- a/packages/core/src/types/route.ts +++ b/packages/core/src/types/route.ts @@ -1,17 +1,17 @@ -import { IRouteObject } from '@shuvi/router'; - -export interface IRouteBase extends IRouteObject { +export interface IRouteBase { + path?: string; + exact?: boolean; + routes?: IRouteBase[]; [x: string]: any; } export interface IRouteConfig extends IRouteBase { - children?: IRouteConfig[]; - name?: string; + routes?: IRouteConfig[]; component: string; } export interface IRoute extends IRouteBase { id: string; component: any; - children?: IRoute[]; + routes?: IRoute[]; } diff --git a/packages/router-react/src/types.ts b/packages/router-react/src/types.ts index b2f06fcaf..3f9d67a83 100644 --- a/packages/router-react/src/types.ts +++ b/packages/router-react/src/types.ts @@ -5,8 +5,7 @@ import { InitialEntry, Location, State, - To, - IRouteObject as RouteObject + To } from '@shuvi/router'; export interface ILocationContextObject { @@ -65,7 +64,16 @@ export interface INavigateFunction { (delta: number): void; } -export type IRouteObject = RouteObject; +/** + * A route object represents a logical route, with (optionally) its child + * routes organized in a tree-like structure. + */ +export interface IRouteObject { + caseSensitive: boolean; + children?: IRouteObject[]; + element: React.ReactNode; + path: string; +} /** * A "partial route" object is usually supplied by the user and may omit diff --git a/packages/router/src/types.ts b/packages/router/src/types.ts index 01467d347..238c14552 100644 --- a/packages/router/src/types.ts +++ b/packages/router/src/types.ts @@ -3,14 +3,14 @@ import { History } from 'history'; export type IParams = Record; export interface IRouteObject { - caseSensitive?: boolean; + caseSensitive: boolean; children?: IRouteObject[]; - element?: Element; // For react will be React.Element + element: Element; // For react will be React.Element path: string; } -export interface IRouteMatch { - route: T; +export interface IRouteMatch { + route: IRouteObject; pathname: string; params: IParams; } diff --git a/packages/runtime-react/src/lib/index.ts b/packages/runtime-react/src/lib/index.ts index 815cb65cf..901d5187d 100644 --- a/packages/runtime-react/src/lib/index.ts +++ b/packages/runtime-react/src/lib/index.ts @@ -1,9 +1,10 @@ import React from 'react'; -import { matchRoutes } from '@shuvi/core'; +import { matchRoutes as reactRouterMatchRoutes } from 'react-router-config'; import { IApi, Runtime, APIHooks } from '@shuvi/types'; import { resolveAppFile, resolveDep } from './paths'; import { config as configBundler } from './bundler/config'; +import IRouteBase = Runtime.IRouteBase; import RouteConfig = Runtime.IRouteConfig; class ReactRuntime implements Runtime.IRuntime> { @@ -52,8 +53,8 @@ loadRouteComponent(() => import(/* webpackChunkName: "page-${route.id}" */"${com } // TODO: move this to core - matchRoutes(routes: RouteConfig[], pathname: string) { - return matchRoutes(routes, pathname); + matchRoutes(routes: IRouteBase[], pathname: string): Runtime.IMatchedRoute[] { + return reactRouterMatchRoutes(routes, pathname) as Runtime.IMatchedRoute[]; } getViewModulePath(): string { diff --git a/packages/runtime-react/src/shuvi-app/router/matchRoutes.ts b/packages/runtime-react/src/shuvi-app/router/matchRoutes.ts new file mode 100644 index 000000000..0408ca0f5 --- /dev/null +++ b/packages/runtime-react/src/shuvi-app/router/matchRoutes.ts @@ -0,0 +1,12 @@ +import { Runtime } from '@shuvi/types'; +import { matchRoutes as reactRouterMatchRoutes } from 'react-router-config'; + +import IMatchedRoute = Runtime.IMatchedRoute; +import IRouteBase = Runtime.IRouteBase; + +export function matchRoutes( + routes: IRouteBase[], + pathname: string +): IMatchedRoute[] { + return (reactRouterMatchRoutes(routes, pathname) as any) as IMatchedRoute[]; +} diff --git a/packages/runtime-react/src/shuvi-app/router/renderRoutes.tsx b/packages/runtime-react/src/shuvi-app/router/renderRoutes.tsx index 42258522d..5de1bd358 100644 --- a/packages/runtime-react/src/shuvi-app/router/renderRoutes.tsx +++ b/packages/runtime-react/src/shuvi-app/router/renderRoutes.tsx @@ -19,7 +19,6 @@ function renderRoutes( appContext?: Data; } = {} ) { - // TODO migration return routes && routes.length ? ( {routes.map((route, i) => ( diff --git a/packages/runtime-react/src/shuvi-app/view/ReactView.client.tsx b/packages/runtime-react/src/shuvi-app/view/ReactView.client.tsx index c9d10d7b3..292bbf871 100644 --- a/packages/runtime-react/src/shuvi-app/view/ReactView.client.tsx +++ b/packages/runtime-react/src/shuvi-app/view/ReactView.client.tsx @@ -2,10 +2,10 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { Router } from 'react-router-dom'; import qs from 'querystring'; -import { matchRoutes } from '@shuvi/core'; import { Runtime } from '@shuvi/types'; import { History } from '../router/history'; import { setHistory } from '../router/router'; +import { matchRoutes } from '../router/matchRoutes'; import AppContainer from '../AppContainer'; import { IRoute } from '../types'; import { HeadManager, HeadManagerContext } from '../head'; @@ -21,8 +21,8 @@ function getRouteParams(routes: IRoute[], pathname: string) { const matchedRoutes = matchRoutes(routes, pathname); const params: Runtime.IParams = {}; for (let index = 0; index < matchedRoutes.length; index++) { - const matchedRoute = matchedRoutes[index]; - Object.assign(params, matchedRoute.params); + const { match } = matchedRoutes[index]; + Object.assign(params, match.params); } return params; } diff --git a/packages/runtime-react/src/shuvi-app/view/ReactView.server.tsx b/packages/runtime-react/src/shuvi-app/view/ReactView.server.tsx index e66f69fc0..033fd84df 100644 --- a/packages/runtime-react/src/shuvi-app/view/ReactView.server.tsx +++ b/packages/runtime-react/src/shuvi-app/view/ReactView.server.tsx @@ -1,6 +1,5 @@ import React from 'react'; import { renderToString } from 'react-dom/server'; -import { matchRoutes } from '@shuvi/core'; import { Runtime } from '@shuvi/types'; import { Router } from 'react-router-dom'; import { createServerHistory } from '../router/history'; @@ -10,6 +9,7 @@ import AppContainer from '../AppContainer'; import { IReactServerView, IReactAppData } from '../types'; import { Head } from '../head'; import { createRedirector } from '../utils/createRedirector'; +import { matchRoutes } from '../router/matchRoutes'; import IAppComponent = Runtime.IAppComponent; import IRouteComponent = Runtime.IRouteComponent; @@ -43,11 +43,11 @@ export class ReactServerView implements IReactServerView { const pendingDataFetchs: Array<() => Promise> = []; const params: IParams = {}; for (let index = 0; index < matchedRoutes.length; index++) { - const matchedRoute = matchedRoutes[index]; - const comp = matchedRoute.route.component as + const { route, match } = matchedRoutes[index]; + const comp = route.component as | IRouteComponent | undefined; - Object.assign(params, matchedRoute.params); + Object.assign(params, match.params); if (comp && comp.getInitialProps) { pendingDataFetchs.push(async () => { const props = await comp.getInitialProps!({ @@ -55,10 +55,10 @@ export class ReactServerView implements IReactServerView { pathname, query, appContext, - params: matchedRoute.params, + params: match.params, redirect: redirector.handler }); - routeProps[matchedRoute.route.id] = props || {}; + routeProps[route.id] = props || {}; }); } } diff --git a/packages/shuvi/src/api/api.ts b/packages/shuvi/src/api/api.ts index b4645eaff..984e7d201 100644 --- a/packages/shuvi/src/api/api.ts +++ b/packages/shuvi/src/api/api.ts @@ -191,7 +191,6 @@ class Api extends Hookable implements IApi { componentDir: this.paths.pagesDir }); routes.push({ - path: '*', component: this.resolveAppFile('core', '404'), name: '404' }); diff --git a/packages/shuvi/src/api/types.ts b/packages/shuvi/src/api/types.ts index f57c66911..7b3885f2a 100644 --- a/packages/shuvi/src/api/types.ts +++ b/packages/shuvi/src/api/types.ts @@ -9,7 +9,7 @@ export type IBuiltResource = { matchRoutes( routes: Runtime.IRouteConfig[], pathname: string - ): Runtime.IMatchedRoute[]; + ): Runtime.IMatchedRoute[]; }; documentTemplate: any; clientManifest: Bundler.IManifest; diff --git a/packages/shuvi/src/lib/routes.ts b/packages/shuvi/src/lib/routes.ts index 387d3f300..28247c1aa 100644 --- a/packages/shuvi/src/lib/routes.ts +++ b/packages/shuvi/src/lib/routes.ts @@ -6,8 +6,6 @@ export type Templates = { [K in keyof T]?: (v: T[K], route: T & { id: string }) => string; }; -type RouteKeysWithoutChildren = keyof Omit; - function genRouteId(filepath: string) { return createHash('md4').update(filepath).digest('hex').substr(0, 4); } @@ -19,14 +17,14 @@ function serializeRoutesImpl( ): string { let res = ''; for (let index = 0; index < routes.length; index++) { - const { children: childRoutes, ...route } = routes[index]; + const { routes: childRoutes, ...route } = routes[index]; const fullpath = route.path ? parentPath + '/' + route.path : parentPath; const id = genRouteId(fullpath); let strRoute = `id: ${JSON.stringify(id)},\n`; const keys = Object.keys(route); for (let index = 0; index < keys.length; index++) { - const key = keys[index] as RouteKeysWithoutChildren; + const key = keys[index]; strRoute += `${key}: `; const customSerialize = templates[key]; if (customSerialize) { @@ -70,8 +68,8 @@ export function normalizeRoutes( : path.resolve(option.componentDir, route.component); route.component = absPath.replace(/\\/g, '/'); - if (route.children && route.children.length > 0) { - route.children = normalizeRoutes(route.children, option); + if (route.routes && route.routes.length > 0) { + route.routes = normalizeRoutes(route.routes, option); } res.push(route); } diff --git a/packages/types/src/runtime.d.ts b/packages/types/src/runtime.d.ts index b33290299..a6944051c 100644 --- a/packages/types/src/runtime.d.ts +++ b/packages/types/src/runtime.d.ts @@ -11,7 +11,6 @@ import { IInitAppPlugins, IAppPluginRecord } from '@shuvi/core'; -import { IRouteMatch, IRouteObject } from '@shuvi/router'; import { ParsedUrlQuery } from 'querystring'; import { IApi } from '../index'; import { IManifest } from './bundler'; @@ -39,7 +38,17 @@ export interface IRequest { headers: IncomingHttpHeaders; } -export type IMatchedRoute = IRouteMatch; +export interface IMatchedRoute< + Params extends { [K in keyof Params]?: string } = {} +> { + route: IRouteBase; + match: { + params: Params; + isExact: boolean; + path: string; + url: string; + }; +} export type IHtmlAttrs = { textContent?: string } & { [x: string]: string | number | undefined | boolean; @@ -231,10 +240,7 @@ export interface IRuntime { route: IRouteConfig & { id: string } ): string; - matchRoutes( - routes: IRouteConfig[], - pathname: string - ): IMatchedRoute[]; + matchRoutes(routes: IRouteConfig[], pathname: string): IMatchedRoute[]; getRouterModulePath(): string;