diff --git a/packages/docusaurus-types/src/index.d.ts b/packages/docusaurus-types/src/index.d.ts index cead1c6ed2..7d86042aee 100644 --- a/packages/docusaurus-types/src/index.d.ts +++ b/packages/docusaurus-types/src/index.d.ts @@ -12,6 +12,7 @@ import type {ParsedUrlQueryInput} from 'querystring'; import type Joi from 'joi'; import type {Overwrite, DeepPartial} from 'utility-types'; import type {Location} from 'history'; +import type Loadable from 'react-loadable'; export type ReportingSeverity = 'ignore' | 'log' | 'warn' | 'error' | 'throw'; @@ -378,8 +379,7 @@ export interface RouteConfig { export type Route = { readonly path: string; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - readonly component: any; + readonly component: ReturnType; readonly exact?: boolean; readonly routes?: Route[]; }; diff --git a/packages/docusaurus/src/server/brokenLinks.ts b/packages/docusaurus/src/server/brokenLinks.ts index 8407205b19..a085135a98 100644 --- a/packages/docusaurus/src/server/brokenLinks.ts +++ b/packages/docusaurus/src/server/brokenLinks.ts @@ -5,10 +5,7 @@ * LICENSE file in the root directory of this source tree. */ -import { - matchRoutes, - type RouteConfig as RRRouteConfig, -} from 'react-router-config'; +import {matchRoutes} from 'react-router-config'; import fs from 'fs-extra'; import _ from 'lodash'; import type {RouteConfig, ReportingSeverity} from '@docusaurus/types'; @@ -23,11 +20,6 @@ import path from 'path'; import combinePromises from 'combine-promises'; import logger from '@docusaurus/logger'; -function toReactRouterRoutes(routes: RouteConfig[]): RRRouteConfig[] { - // @ts-expect-error: types incompatible??? - return routes as RRRouteConfig[]; -} - type BrokenLink = { link: string; resolvedLink: string; @@ -47,10 +39,9 @@ function getPageBrokenLinks({ pageLinks: string[]; routes: RouteConfig[]; }): BrokenLink[] { - // ReactRouter is able to support links like ./../somePath - // but matchRoutes does not do this resolving internally - // we must resolve the links before using matchRoutes - // resolvePathname is used internally by ReactRouter + // ReactRouter is able to support links like ./../somePath but `matchRoutes` + // does not do this resolution internally. We must resolve the links before + // using `matchRoutes`. `resolvePathname` is used internally by React Router function resolveLink(link: string) { const resolvedLink = resolvePathname(onlyPathname(link), pagePath); return {link, resolvedLink}; @@ -58,7 +49,10 @@ function getPageBrokenLinks({ function isBrokenLink(link: string) { 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)); 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 * want to match broken links like /docs/brokenLink against /docs/*. For this - * reason, we only consider the "final routes", that do not have subroutes. - * We also need to remove the match all 404 route + * reason, we only consider the "final routes" that do not have subroutes. + * We also need to remove the match-all 404 route */ function filterIntermediateRoutes(routesInput: RouteConfig[]): RouteConfig[] { const routesWithout404 = routesInput.filter((route) => route.path !== '*'); diff --git a/packages/docusaurus/src/server/routes.ts b/packages/docusaurus/src/server/routes.ts index c2105c07ce..ba5508bfd9 100644 --- a/packages/docusaurus/src/server/routes.ts +++ b/packages/docusaurus/src/server/routes.ts @@ -119,28 +119,18 @@ function getModulePath(target: Module): string { return `${target.path}${queryStr}`; } -type LoadedRoutes = { - registry: { - [chunkName: string]: ChunkRegistry; - }; - routesConfig: string; - routesChunkNames: { - [routePath: string]: ChunkNames; - }; - routesPaths: string[]; -}; - export default async function loadRoutes( pluginsRouteConfigs: RouteConfig[], baseUrl: string, -): Promise { - const registry: { - [chunkName: string]: ChunkRegistry; - } = {}; +): Promise<{ + registry: {[chunkName: string]: ChunkRegistry}; + routesConfig: string; + routesChunkNames: {[routePath: string]: ChunkNames}; + routesPaths: string[]; +}> { + const registry: {[chunkName: string]: ChunkRegistry} = {}; const routesPaths: string[] = [normalizeUrl([baseUrl, '404.html'])]; - const routesChunkNames: { - [routePath: string]: ChunkNames; - } = {}; + const routesChunkNames: {[routePath: string]: ChunkNames} = {}; // This is the higher level overview of route code generation. function generateRouteCode(routeConfig: RouteConfig): string { @@ -254,10 +244,7 @@ function genRouteChunkNames( modulePath, )}')`; - registry[chunkName] = { - loader, - modulePath, - }; + registry[chunkName] = {loader, modulePath}; return chunkName; }