mirror of
https://github.com/facebook/docusaurus.git
synced 2025-04-30 18:58:36 +02:00
refactor(core): minor routes type improvement (#6929)
This commit is contained in:
parent
bfe7ca6237
commit
f70ddf7e69
3 changed files with 21 additions and 40 deletions
4
packages/docusaurus-types/src/index.d.ts
vendored
4
packages/docusaurus-types/src/index.d.ts
vendored
|
@ -12,6 +12,7 @@ import type {ParsedUrlQueryInput} from 'querystring';
|
||||||
import type Joi from 'joi';
|
import type Joi from 'joi';
|
||||||
import type {Overwrite, DeepPartial} from 'utility-types';
|
import type {Overwrite, DeepPartial} from 'utility-types';
|
||||||
import type {Location} from 'history';
|
import type {Location} from 'history';
|
||||||
|
import type Loadable from 'react-loadable';
|
||||||
|
|
||||||
export type ReportingSeverity = 'ignore' | 'log' | 'warn' | 'error' | 'throw';
|
export type ReportingSeverity = 'ignore' | 'log' | 'warn' | 'error' | 'throw';
|
||||||
|
|
||||||
|
@ -378,8 +379,7 @@ export interface RouteConfig {
|
||||||
|
|
||||||
export type Route = {
|
export type Route = {
|
||||||
readonly path: string;
|
readonly path: string;
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
readonly component: ReturnType<typeof Loadable>;
|
||||||
readonly component: any;
|
|
||||||
readonly exact?: boolean;
|
readonly exact?: boolean;
|
||||||
readonly routes?: Route[];
|
readonly routes?: Route[];
|
||||||
};
|
};
|
||||||
|
|
|
@ -5,10 +5,7 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import {
|
import {matchRoutes} from 'react-router-config';
|
||||||
matchRoutes,
|
|
||||||
type RouteConfig as RRRouteConfig,
|
|
||||||
} from 'react-router-config';
|
|
||||||
import fs from 'fs-extra';
|
import fs from 'fs-extra';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import type {RouteConfig, ReportingSeverity} from '@docusaurus/types';
|
import type {RouteConfig, ReportingSeverity} from '@docusaurus/types';
|
||||||
|
@ -23,11 +20,6 @@ import path from 'path';
|
||||||
import combinePromises from 'combine-promises';
|
import combinePromises from 'combine-promises';
|
||||||
import logger from '@docusaurus/logger';
|
import logger from '@docusaurus/logger';
|
||||||
|
|
||||||
function toReactRouterRoutes(routes: RouteConfig[]): RRRouteConfig[] {
|
|
||||||
// @ts-expect-error: types incompatible???
|
|
||||||
return routes as RRRouteConfig[];
|
|
||||||
}
|
|
||||||
|
|
||||||
type BrokenLink = {
|
type BrokenLink = {
|
||||||
link: string;
|
link: string;
|
||||||
resolvedLink: string;
|
resolvedLink: string;
|
||||||
|
@ -47,10 +39,9 @@ function getPageBrokenLinks({
|
||||||
pageLinks: string[];
|
pageLinks: string[];
|
||||||
routes: RouteConfig[];
|
routes: RouteConfig[];
|
||||||
}): BrokenLink[] {
|
}): BrokenLink[] {
|
||||||
// ReactRouter is able to support links like ./../somePath
|
// ReactRouter is able to support links like ./../somePath but `matchRoutes`
|
||||||
// but matchRoutes does not do this resolving internally
|
// does not do this resolution internally. We must resolve the links before
|
||||||
// we must resolve the links before using matchRoutes
|
// using `matchRoutes`. `resolvePathname` is used internally by React Router
|
||||||
// resolvePathname is used internally by ReactRouter
|
|
||||||
function resolveLink(link: string) {
|
function resolveLink(link: string) {
|
||||||
const resolvedLink = resolvePathname(onlyPathname(link), pagePath);
|
const resolvedLink = resolvePathname(onlyPathname(link), pagePath);
|
||||||
return {link, resolvedLink};
|
return {link, resolvedLink};
|
||||||
|
@ -58,7 +49,10 @@ function getPageBrokenLinks({
|
||||||
|
|
||||||
function isBrokenLink(link: string) {
|
function isBrokenLink(link: string) {
|
||||||
const matchedRoutes = [link, decodeURI(link)]
|
const matchedRoutes = [link, decodeURI(link)]
|
||||||
.map((l) => matchRoutes(toReactRouterRoutes(routes), l))
|
// @ts-expect-error: React router types RouteConfig with an actual React
|
||||||
|
// component, but we load route components with string paths.
|
||||||
|
// We don't actually access component here, so it's fine.
|
||||||
|
.map((l) => matchRoutes(routes, l))
|
||||||
.reduce((prev, cur) => prev.concat(cur));
|
.reduce((prev, cur) => prev.concat(cur));
|
||||||
return matchedRoutes.length === 0;
|
return matchedRoutes.length === 0;
|
||||||
}
|
}
|
||||||
|
@ -69,8 +63,8 @@ function getPageBrokenLinks({
|
||||||
/**
|
/**
|
||||||
* The route defs can be recursive, and have a parent match-all route. We don't
|
* The route defs can be recursive, and have a parent match-all route. We don't
|
||||||
* want to match broken links like /docs/brokenLink against /docs/*. For this
|
* want to match broken links like /docs/brokenLink against /docs/*. For this
|
||||||
* reason, we only consider the "final routes", that do not have subroutes.
|
* reason, we only consider the "final routes" that do not have subroutes.
|
||||||
* We also need to remove the match all 404 route
|
* We also need to remove the match-all 404 route
|
||||||
*/
|
*/
|
||||||
function filterIntermediateRoutes(routesInput: RouteConfig[]): RouteConfig[] {
|
function filterIntermediateRoutes(routesInput: RouteConfig[]): RouteConfig[] {
|
||||||
const routesWithout404 = routesInput.filter((route) => route.path !== '*');
|
const routesWithout404 = routesInput.filter((route) => route.path !== '*');
|
||||||
|
|
|
@ -119,28 +119,18 @@ function getModulePath(target: Module): string {
|
||||||
return `${target.path}${queryStr}`;
|
return `${target.path}${queryStr}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
type LoadedRoutes = {
|
|
||||||
registry: {
|
|
||||||
[chunkName: string]: ChunkRegistry;
|
|
||||||
};
|
|
||||||
routesConfig: string;
|
|
||||||
routesChunkNames: {
|
|
||||||
[routePath: string]: ChunkNames;
|
|
||||||
};
|
|
||||||
routesPaths: string[];
|
|
||||||
};
|
|
||||||
|
|
||||||
export default async function loadRoutes(
|
export default async function loadRoutes(
|
||||||
pluginsRouteConfigs: RouteConfig[],
|
pluginsRouteConfigs: RouteConfig[],
|
||||||
baseUrl: string,
|
baseUrl: string,
|
||||||
): Promise<LoadedRoutes> {
|
): Promise<{
|
||||||
const registry: {
|
registry: {[chunkName: string]: ChunkRegistry};
|
||||||
[chunkName: string]: ChunkRegistry;
|
routesConfig: string;
|
||||||
} = {};
|
routesChunkNames: {[routePath: string]: ChunkNames};
|
||||||
|
routesPaths: string[];
|
||||||
|
}> {
|
||||||
|
const registry: {[chunkName: string]: ChunkRegistry} = {};
|
||||||
const routesPaths: string[] = [normalizeUrl([baseUrl, '404.html'])];
|
const routesPaths: string[] = [normalizeUrl([baseUrl, '404.html'])];
|
||||||
const routesChunkNames: {
|
const routesChunkNames: {[routePath: string]: ChunkNames} = {};
|
||||||
[routePath: string]: ChunkNames;
|
|
||||||
} = {};
|
|
||||||
|
|
||||||
// This is the higher level overview of route code generation.
|
// This is the higher level overview of route code generation.
|
||||||
function generateRouteCode(routeConfig: RouteConfig): string {
|
function generateRouteCode(routeConfig: RouteConfig): string {
|
||||||
|
@ -254,10 +244,7 @@ function genRouteChunkNames(
|
||||||
modulePath,
|
modulePath,
|
||||||
)}')`;
|
)}')`;
|
||||||
|
|
||||||
registry[chunkName] = {
|
registry[chunkName] = {loader, modulePath};
|
||||||
loader,
|
|
||||||
modulePath,
|
|
||||||
};
|
|
||||||
return chunkName;
|
return chunkName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue